队列的基本概念
定义:队列是一种受限线性结构,只允许一端进入一端出去,先进先出。
基本描述
队头:允许删除的一端
队尾:允许插入的一端
空队列:为空的队列
入队:从队尾插入元素队列
出队:从队出队删除元素、
基本操作
InitQueue(&Q):队列初始化,创造一个空队列。
QueueElemtype(Q):判断队列是否为空。
EnQueue(&Q):入队
DnQueue(&Q):出队
GetHead(Q)检查队头元素。
队列的存储机构
结构体定义
#define MaxSize 50
typedef struct{
ElmeType data[MaxSize];
int front,rear;
}SqQueue;
顺序存储
初始化:判栈空front=0,rear==0
入队:将插入元素送到队尾,然后队尾指针加一
出队:将队头元素取出,然后队头指针加一
顺序队列的缺点:当front和rear都到了分配数组的底端,就会出现假溢出的现象,为了解决这个缺点引入循环队列。
循环队列
把顺序队列臆造为一个环状空间,把顺序表从逻辑上视为一个环,称为循环队列,当首指针front=MaxSize-1后,再前进一个位置自动到0,可以利用取余运算来完成。
初始化:front=rear=0
队首指针进一:front=(front+1)%MaxSize
队尾指针进一:rear=(rear+1)%MaxSize
队列长度:(rear+MaxSize-front)%MaxSize
当队尾指针追上队首时判断是否为满会纯在和判断空一样的条件都是front=rear,解决方法有三
一、牺牲一个单元来区分队空和队满,队头指针在队尾指针的下一位作为队满的标志
队满条件:(rear+1)%MaxSize==front
队空条件:rear=front
队列长度:(rear-front+MaxSize)%MaxSize
二、在类型中添加一个表示队长的数据队空的条件是size=0,队满的条件是size=MaxSize,这两种情况都有front=rear
三、增加一个数据成员tag,删除操作时tag置为0,插入操作时tag置为1.当因为删除操作导致front=rear的情况则为队空2.当因插入操作导致front=rear的情况则为队满。
循环队列的实现
//初始化
void InitQueue(SqQueue &Q){
Q.rear=Q.front;
}
//判断队空
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;
}
队列的链式存储
结构体
typedef struct {
ElmeType data;
struct LinkNode *next;
}LinkNode;
typedef struct {
LinkNode *front,*rear;
}LinkQueue;
为了让操作统一,在链表头添加头结点,单链表的表示比较适合于数据元素变动比较大的情况,不存在溢出的问题。
基本操作
/链式存储
typedef struct {
ElmeType data;
struct LinkNode *next;
}LinkNode;
typedef struct {
LinkNode *front,*rear;
}LinkQueue;
//初始化
void LinkInitQueue(LinkQueue &Q){
Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
Q.front->next=NULL;
}
//判断空
bool LinkIsEpty(LinkQueue Q){
if (Q.front=Q.rear)
return true;
else
return false;
}
//入队
void EnQueue(LinkQueue &Q,ElemType x){
LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
s->data
}
//出队
bool DeQueue(LinkQueue &Q ,ElemType &x){
if (Q.front=Q.rear)
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;
}
双端队列
双端队列是指队列分前端和后端,两端都可以入队和出队,输出受限双端队列和输入受限的双端队对列
真题
2014:
队列列头出队,列低入队