前面已经过了一边栈,接下来开始队列的学习
队列就想象成一根吸管,喝珍珠奶茶的时候就是吸珍珠,谁先被吸到谁先入嘴知道吧。
画个图理解一下吧
就一个重点:先进先出,后进后出
还有就是:只允许在一端插入的叫队头,只允许在一端删除的叫队尾
因为循环队列可以优化顺序队列空间利用率,避免“假溢出”的现象,所有我们一循环队列为例
队列的基本操作 (顺序循环队列)
1. 定义结构体(循环队列)
#define MAX_SIZE 7 // 队列最大容量
typedef struct {
int data[MAX_SIZE];
int front; // 保存队头元素的队头指针
int rear; // 保存队尾元素的队尾指针
} Queue;
2. 初始化队列
void initQueue(Queue *q) {
q->front = 0;
q->rear = 0;
}
如何判断队空队满?
循环队列判满: (rear+1)%MAX_SIZE==front
循环队列判空:rear==front
3. 入队(Enqueue)
int enqueue(Queue *q, int value) {
if (isFull(q)) {
printf("队列已满,无法入队\n");
return -1;
}
q->data[q->rear] = value;
q->rear = (q->rear + 1) % MAX_SIZE;
return 0;
}
4.出队(Dequeue)
int dequeue(Queue *q) {
if (isEmpty(q)) {
printf("队列为空,无法出队\n");
return -1;
}
int value = q->data[q->front];
q->front = (q->front + 1) % MAX_SIZE;
return value;
}
5.判空
int isEmpty(Queue *q) {
return q->front == q->rear;
}
6.判断队列是否已满(循环队列)
int isFull(Queue *q) {
return (q->rear + 1) % MAX_SIZE == q->front;
}
7. 获取队头元素(不删除)
int peek(Queue *q) {
if (isEmpty(q)) {
printf("队列为空\n");
return -1;
}
return q->data[q->front];
}
8. 获取当前队列长度
int queueSize(Queue *q) {
return (q->rear - q->front + MAX_SIZE) % MAX_SIZE;
}
最后记住队列和栈的区别就行:队列先进先出,栈先进后出
然后就是为了避免循环队列中的判空和判满条件冲突,我们会在内存中浪费一个空间
即当(rear + 1) % MAX_SIZE == front
时表示队列已满。