C实现队列
简介
队列是一种常见的数据结构,类似于现实生活中的排队场景。它是一种 先进先出(FIFO,First-In-First-Out) 的数据结构,即最先进入队列的元素最先被移出。
队列有两个主要操作:
- 入队(enqueue):将元素添加到队列的尾部。
- 出队(dequeue):从队列的头部移除元素。
除了这两个基本操作外,队列通常还包括以下功能:
- 获取队头元素(front):获取队列头部的元素,但不移除它。
- 判断队列是否为空:检查队列是否没有任何元素。
- 获取队列长度:获取队列中元素的个数。
队列可以用于许多应用场景,如任务调度、广度优先搜索、缓冲区管理等。在计算机科学中,队列通常被用作解决问题的数据结构之一,因为它提供了良好的顺序性和操作性能。
核心思路
采用了 循环队列 的思想。循环队列是一种通过数组实现的队列,它的特点是队列的存储空间是循环利用的,即当队列的尾部指针到达数组的末尾时,会绕回到数组的开头,形成一个循环。
我们使用了两个指针 head 和 rear 来分别指示队列的头部和尾部。这两个指针在队列操作中起到关键作用:
- head 指针用于指示队列的头部,即队首元素的位置。
- rear 指针用于指示队列的尾部,即下一个元素入队的位置。
这种设计使得队列的入队和出队操作可以在 O(1) 的时间复杂度内完成,因为不需要像链式队列那样遍历到尾部或头部。而且由于是循环队列,没有了队列满的情况,使得队列的空间利用率更高。
代码实现
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义队列结构体
typedef struct Queue{
int data[MAX_SIZE];
int head;
int rear;
} Queue;
/* void initQueue(Queue* queue) {
queue->head = 0;
queue->rear = 0;
} */
// 初始化队列
Queue* queueCreate() {
Queue* queue = (Queue*)malloc(sizeof(Queue));
queue->head = 0;
queue->rear = 0;
return queue;
}
// 判断队列是否为空
int isEmpty(Queue* queue) {
return queue->head == queue->rear;
}
// 判断队列是否已满
int isFull(Queue* queue) {
return (queue->rear + 1) % MAX_SIZE == queue->head;
}
// 入队操作
void enQueue(Queue* queue, int value) {
if (isFull(queue))
{
printf("不能入队\n");
return;
}
queue->data[queue->rear] = value;
queue->rear = (queue->rear + 1) % MAX_SIZE;
}
// 出队操作
int deQueue(Queue* queue) {
if (isEmpty(queue)) {
printf("不能出队\n");
exit(1);
}
int value = queue->data[queue->head];
queue->head = (queue->head + 1) % MAX_SIZE;
return value;
}
// 获取队头元素
int front(Queue* queue) {
if (isEmpty(queue)) {
printf("无法获取\n");
exit(1);
}
return queue->data[queue->head];
}
// 获取队列长度
int size(Queue* queue) {
return (queue->rear - queue->head + MAX_SIZE) % MAX_SIZE;
}
实例化代码如下:
int main() {
Queue* queue = queueCreate();
enQueue(queue, 1);
enQueue(queue, 2);
enQueue(queue, 3);
printf("队列长度:%d\n", size(queue));
printf("出队元素:%d\n", deQueue(queue));
printf("出队元素:%d\n", deQueue(queue));
printf("队头元素:%d\n", front(queue));
return 0;
}