一、什么叫做队列❓
一种可以实现【先进先出】的存储结构
二、队列的分类
-
链式队列
链式队列示意图:链表形式实现,front即链表的pHead,rear:臀,屁股
提示
一头进一头出,先进先出。实现参考链表。
front指向第一个有效元素
rear指向最后一个有效元素的下一个元素,rear本身是无数据元素,类似于链表的pHead -
静态(数组)队列
- 静态队列通常必须是循环队列
- 学习循环队列必须搞懂的7个问题。
-
为什么必须是循环队列?
-
循环队列需要几个参数确定?
1)front :队列头,先进的元素,先出的元素- rear : 队列尾,臀。无数据,只起到方便操作作用
-
循环队列各个参数的含义?
- front 队列头的含义
- rear
- 2个参数不同场合有不同的含义,建议初学者先记住,然后慢慢体会。
- 队列初始化: front 和 rear 皆为0
- 队列非空:
front:队列的第一个有效元素
rear:队列的最后一个有效元素的后一个值为NULL的元素 - 队列为空:font和rear的值相等,但不一定是0️⃣
-
循环队列入队伪算法讲解
image.png -
循环队列出队伪算法讲解
- 入队两步骤:
- 将值存入r所代表的位置
- 错误的写法r = r + 1;
正确的写法:r = (r + 1) % 数组的长度
-
- 出队步骤:
- 保存front的值 (如果有必要的话)
- 错误的写法f = f + 1;
正确的写法:f = (f + 1) % 数组的长度
- 如何判定循环队列是否为空
如果front 和rear的值相等,则该队列肯定为空 -
如何判断循环队列已满
队列满时front 和 rear在同一位置,对列为空时也在同一位置
判断方式
- 方式一:(❌)
当元素个数 = 数组长度时,即:front = rear时,标记为满。 - 方式二:(常用)(✅)
当元素个数 = 数组长度 - 1 时,即:front和rear相邻时,标记为满。
解决方式
方式一 (不采用❌)
- 新增加一长度字段来记录元素个数。
麻烦,每次新增、删除时都需要取维护
方式二 (采用✅)
- 数组少用一个元素,
- 判断front 和 rear 挨着,并且是rear的next元素是front
- 而不是front的下一个元素是rear(只剩下一个元素)
if( (rear + 1) % 数组长度 == front)
{
已满
}
else
{
不满
}
队列代码实现
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct ArrayQueue {
int * pBase; //数据域
int front; //指针域
int rear; //臀
} QUEUE, * PQUEUE;
void init(PQUEUE);
bool en_queue(PQUEUE, int);
bool out_queue(PQUEUE pQ,int * pVal);
void show(PQUEUE);
bool isEmpty(PQUEUE pQ);
bool isFull(PQUEUE);
void show(PQUEUE pQ);
int main(void) {
QUEUE q;
init(&q);
en_queue(&q,1);
en_queue(&q,2);
en_queue(&q,3);
en_queue(&q,4);
en_queue(&q,5);
en_queue(&q,6);
en_queue(&q,7);
en_queue(&q,8);
show(&q);
int i;
printf("开始出队:\n");
out_queue(&q,&i);
show(&q);
printf("开始出队:\n");
out_queue(&q,&i);
show(&q);
return 0;
}
void init(PQUEUE pQ) {
pQ->pBase = (int *)malloc(sizeof(int) * 6);
pQ->front = 0;
pQ->rear = 0;
}
bool en_queue(PQUEUE pQ, int val) {
if(isFull(pQ))
{
printf("插入值:%d时 队列已满\n", val);
return false;
exit(-1);
}
else
{
pQ->pBase[pQ->rear] = val;
pQ->rear++;
return true;
}
}
bool out_queue(PQUEUE pQ,int * pVal) {
if(isEmpty(pQ))
{
return false;
}
else
{
*pVal = pQ->pBase[pQ->front];
pQ->front = (pQ->front + 1) % 6;
return true;
}
}
bool isEmpty(PQUEUE pQ) {
if(pQ->front == pQ->rear)
return true;
else
return false;
}
bool isFull(PQUEUE pQ) {
if((pQ->rear + 1) % 6 == pQ->front)
return true;
else
return false;
}
void show(PQUEUE pQ) {
int i = pQ->front;
while(i != pQ -> rear) {
printf("%d ", pQ -> pBase[i]);
i = (i+1) % 6;
}
printf("\n");
return;
}
网友评论