1.队列的基本概念
1)定义
- 队列简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在另一端进行删除。向队列中插入元素称为入队;删除元素成为出队
2)特性
- 先进先去
3)队头
- 允许删除的一端
4)队尾
- 允许插入的一端
5)空队列
- 不含任何元素的空表
6)队列常见的基本操作
-
InitQueue(&Q)
- 初始化队列,构造一个空队列Q
-
QueueEmpty(Q)
- 判队列空,若队列Q为空返回true,否则返回false
-
EnQueue(&Q,x)
- 入队,若队列Q未满,将x加入,使之成为新的队尾
-
Dequeue(&Q,&x)
- 出队,若队列Q非空,删除队头元素,并用x返回
-
GetHead(Q,&x)
- 读队头元素,若队列Q非空,则将队头元素赋值给x
2.队列的顺序存储结构
1)队列的顺序存储
-
定义
- 队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置。
-
存储类型
#define MaxSize 50
typedef struct{
ElemType data[MaxSize];
int front,rear;
}SqQueue;
-
初始状态
- Q.front==Q.rear==0
-
进队操作
- 队不满时,先送值到队尾元素,再将队尾指针加1
-
出队操作
- 队不空时,先取队头元素,再将队头指针加1
2)循环队列
-
将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列
-
初始时
- Q.front=Q.rear=0
-
队首指针进1
- Q.front=(Q.front+1)%MaxSize
-
队尾指针进1
- Q.rear=(Q.rear+1)%MaxSize
-
出队入队时
- 指针都按顺时针方向进1
-
队空队满区分方式
-
牺牲一个单元来区分
-
队满条件
- (Q.rear+1)%MaxSize==Q.front
-
队空条件
- Q.rear==Q.front
-
-
增设表示元素个数的数据成员
-
队满条件
- Q.size==MaxSize
-
队空条件
- Q.size==0
-
-
类型中增设tag数据成员
-
队满条件
- Q.front=Q.rear;tag==1(插入导致)
-
队空条件
- Q.front=Q.rear;tag==0(删除导致)
-
-
3)循环队列的操作
- 初始化
void InitQueue(SqQueue &Q){
Q.rear==Q.front=0;
}
- 队列空
bool isEmpty(SqQueue &Q){
if(Q.rear==Q.front) return true;
else return false;
}
- 入队
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front) return false;
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%MaxSize;
return true;
}
- 出队
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front) return false;
X=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
3.队列的链式存储结构
1)队列的链式存储
-
定义
- 队列的链式表示称为链队列,它实际上是一个同时带队头指针和队尾指针的单链表。头指针指向队头结点,尾指针指向队尾结点
-
存储类型
- typedef struct LinkNode{ ElemType data; struct LinkNode *next; }LinkNode; typedef struct{ typedef *front *rear; }LinkQueue;
-
建议采用有头结点链表
2)链式队列的基本操作
- 初始化
void InitQueue(LinkQueue &Q){
Q.rear=Q.front=(LinkNode*)malloc(sizeof(LinkNode)); //建立头结点
Q.front->next=NULL; //初始为空
}
- 判队空
bool isEmpty(LinkQueue Q){
if(Q.rear==Q.front) return true;
else return false;
}
- 入队
bool EnQueue(LinkQueue &Q,ElemType x){
LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
s.data=x; s->next=NULL;
Q.rear->next=s;
Q.rear=s;
}
- 出队
bool DeQueue(LinkQueue &Q,ElemType &x){
if(Q.rear=Q.front) return false;
LinkNode *p=Q.front->next;
x=p->data;
Q.front->next=p->next;
if(Q.rear==p){
Q.rear=Q.front;
free(p);
return true;
}
4.双端队列
1)定义
- 两端都可以进行入队和出队操作的队列
2)输出受限的双端队列
- 允许一端进行插入和删除,但在另一端只允许插入
3)输入受限的双端队列
- 允许一端进行插入和删除,但在另一端只允许删除