数据结构——队列
文章目录
- 数据结构——队列
- 前言
- 队列基本概念
- 队列的基本操作
- 队列的顺序存储结构
- 创建顺序队列代码
- 入队操作代码
- 出队操作代码
- 顺序队列的关键语句
- 队列的链式存储结构
- 链式队列初始化
- 链式队列判断空
- 链式队列的入队操作
- 链式队列的出队操作
- 循环队列
- 循环队列基本思想
- 1. 循环队列入队列操作
- 2.循环队列出队列操作
- 获取循环队列首元素的算法
- 循环队列六要素
- 总结
前言
- 队列的基本概念
- 顺序队列
- 链式队列
- 循环队列
队列基本概念
1.队列的定义: 队列是一个操作受限的线性表,是一个只允许在表的一端进行插入,在表的另一端进行删除的线性表
2.队尾(rear): 允许插入的一端
3.队头(front): 允许删除的一端
4.队列的特点: 先进先出,后进后出
队列的基本操作
队列的顺序存储结构
队列的顺序存储:附设两个指针front和rear分别指示队头元素和队尾元素的下一个位置
创建顺序队列代码
Create_Qs(front,rear,max){
elemtypr Qs[max];
front=0;
rear=0;
return OK;
}
注:非空队中,头指针始终指向队列头元素的前一个元素,而尾元素始终指向队列尾元素
入队操作代码
指针先动,再赋值
rear++;
a[rear]=x;
或
a[++rear]=x;
出队操作代码
先移动指针,再赋值
front++;
x=[front];
或
x=[++front];
顺序队列的关键语句
队列为空的条件
front==rear;
队列满的条件
rear=maxsize-1;
队列的链式存储结构
队列的链式存储:是一个同时带有队头指针和队尾指针的单链表,头指针指向队头结点,尾指针指向队尾结点
链式队列初始化
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=(LinkNode *)malloc(sizeof(LinkBode)); //建立头结点
Q.front->next=NULL; //初始为空
}
当Q.front == Q.rear ==NULL时链队列为空,通常将链队列设计一个头结点
链式队列为空条件:
Q.front == Q.rear ==NULL
链式队列判断空
bool isEmpty(LinkQueue Q){
if(Q.front==Q.rear) return true;
else return false;
}
链式队列的入队操作
void EnQueue(LinkQueue &Q,ElemType x){
s=(LinkNode *)malloc(sizeof(LinkNode));
s->data=x; s->next=NULL; //创建新结点,插入到链尾
Q.rear->next=s;
Q.rear=s;
}
链式队列的出队操作
bool DeQueue(LinQueue &Q,ElemType &x){
if(Q.front==Q.rear) return false; //空队
p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
}
循环队列
**循环队列定义:**循环队列就是把队列的头和尾连接到一起,从而构成一个环状,实现了有空余空间就能入队的操作
**基本思想:**把队列设成环状,让Qs[0]接在Qs[M-1]之后,若rear+1==M,则令rear=0;
实现: 利用"模"运算
循环队列基本思想
1. 循环队列入队列操作
Insert_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
if((Cq_rear+1)%Cq_max==Cq_front)
return ERROR;
Cq_rear=(Cq_rear+1)%Cq_max;
Cq[Cq_rear]=x;
return OK;
}
2.循环队列出队列操作
Delete_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
if(Cq_front==Cq_rear){
printf("The circular queue is empty!");
return Error;
}
Cq_front=(Cq_front+1)%Cq_max;
x=Cq[Cq_front];
}
出队队位号: Cq_front=(Cq_front+1)%Cq_max;
获取循环队列首元素的算法
Head_Cq(Cq,Cq_rear,Cq_front,Cq_max,x){
if(Cq_front == Cq_rear) //队列为空的条件
printf("The circular queue is emply!");
else
x=Cq[(Cq_front+1)%Cq_max)];
}
循环队列牺牲一个空间,存储头尾指针,如果用a[N]存储一个循环队列,则最多存储N-1个
循环队列六要素
- 入队: rear=(rear+1)%M; Qs[rear]=x; 或Qs[++rear%M]=x;
- 出队: front=(front+1)%M; x=Qs[front]; 或 x=Qs[++front%M];
- 队空: rear==front;
- 队满:(rear+1)%maxsize==front;
- 出队队位号: Cq_front=(Cq_front+1)%Cq_max;
- 循环队列中元素的个数: (Q.rear-Q.front+maxsize)%maxsize;
总结
队列操作核心语句总结
- 顺序队列入队操作: rear++; a[rear]=x; 或 a[++rear]=x;
- 顺序队列出队操作: front++; x=[front]; 或 x=[++front];
- 顺序队列为空的条件: front==rear;
- 顺序队列满的条件: rear=maxsize-1;
- 链式队列为空的条件: Q.front == Q.rear
- 循环队列入队: rear=(rear+1)%M; Qs[rear]=x; 或Qs[++rear%M]=x;
- 循环队列出队: front=(front+1)%M; x=Qs[front]; 或 x=Qs[++front%M];
- 循环队列队空: rear==front;
- 循环队列队满:(rear+1)%maxsize==front;
- 出队队位号: Cq_front=(Cq_front+1)%Cq_max;
- 循环队列中元素的个数: (Q.rear-Q.front+maxsize)%maxsize;