队列的基本概念
定义
- 线性表是具有相同数据类型的n个元素的有限序列,其中n是表长,当n = 0时线性表是一个空表。若用L命名线性表,则一般可以表示成
L = ( a 1 , a 2 , . . . , a i , a i + 1 , . . . , a n ) L = (a_1,a_2,...,a_i,a_{i+1},...,a_n) L=(a1,a2,...,ai,ai+1,...,an) - 栈(Stack)是只允许在一端进行插入或删除操作的线性表(进栈出栈)(FILO)
- 队列(Queue)是只允许从一端插入,从另一端删除的线性表(入队出队)(FIFO)
基本操作
- InitQueue(&Q)
- DestroyQueue(&Q)
- EnQueue(&Q,x)
- DeQueue(&Q,&x)
- GetHead(Q,&x)
- QueueEmpty(Q)
队列的顺序实现
#define MaxSize 10 //队列的最大容量
typedef struct{
ElemType data[MaxSize]; //存放队列数据的数组(顺序存储,静态存储)
int front,rear; //队列头部指针、尾部指针
}SqQueue; //类型命名
//初始化队列
void InitQueue(SqQueue &Q){
Q.front = Q.rear = 0;
}
//队列判空
bool QueueEmpty(SqQueue &Q){
if(Q.rear == Q.front)return ture;
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 ture;
}
//出队(新元素循环插入队首)
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 ture;
}
//获取队列头(复制最先存入的队首元素值)
bool GetHead(SqQueue &Q,ElemType &x){
if(Q.rear == Q.front)return false;
x = Q.data[Q.front];
return true;
}
队列的链式实现
有头节点
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode;
typedef struct{
LNode *front,*rear;
}LinkQueue;
//初始化
bool InitQueue(LinkQueue &Q){
//初始化时front,rear都指向头节点
Q.front = Q.rear = (LNode *)malloc(sizeof(LNode));
if(Q.front == NULL)reuturn false;
Q.front -> next = NULL;
return true;
}
//判断非空
bool IsEmpty(LinkQueue &Q){
if(Q.front == Q.rear)return true;
return false;
}
//新元素入队
bool EnQueue(LinQueue &Q,ElemType x){
LNode *p = (LNode *)malloc(sizeof(LNode));
p -> data = x;
p -> next = NULL;
Q.rear -> next = p;
Q.rear = p;
}
//元素出队
bool DeQueue(LinkQueue &L,ElemType &x){
if(IsEmpty(L))return false;
x = L.front -> data;
LNode *p = (LNode *)malloc(sizeof(LNode));
if(p == NULL)return false;
p = L.front;
L.front = p -> next;
free(p);
return true;
}
//读取front元素
bool GetHead(LinkQueue &L,ElemType &x){
if(L.front == L.rear)return false;
x = L.front -> data;
return true;
}
无头节点
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode;
typedef struct{
LNode *front,*rear;
}LinkQueue;
void InitQueue(LinkQueue &L){
L.front = NULL;
L.rear = NULL;
}
bool IsEmpty(LinkQueue &Q){
if(Q.front == NULL)return true;
return false;
}
bool EnQueue(LinkQueue &Q,ElemType x){
LNode *p = (LNode *)malloc(sizeof(LNode));
if( p == NULL) return false;
p -> data = x;
p -> next = NULL;
if(Q.front == NULL){
Q.front = p;
Q.rear = p;
}else{
Q.rear -> next = p;
Q.rear = p;
}
return true;
}
bool DeQueue(LinkQueue &Q,ElemType &x){
if(Q.front == NULL)return false;
LNode *p = Q.front;
x = p -> data;
Q.front = p -> next;
if(Q.rear = p){
Q.rear = Q.front = NULL;
}
free(p);
return true;
}
bool ReadHead(LinkQueue &Q,ElemType &x){
if(Q.front == NULL)return false;
x = Q.front -> data;
return true;
}
双端队列
- 栈:只允许一端插入和删除的线性表
- 队列:只允许一端插入、另一端删除的线性表
- 双端队列:只允许两端插入、两端删除的线性表()若只是用一端的插入删除功能则效果等同于栈
输入受限的双端队列
输出受限的双端队列
对输出序列合法性的判断
模拟 栈和双端输出正向模拟
注意输出受限的序列,顺序把输出序列排列出来,反向模拟输入即可