赞
踩
队列(Queue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入而在表的另一端进行删除。向队列中插入元素称为入队或进队,删除元素称为出队或离队。最早进队的也是最早出队的,故其操作特性是先进先出FIFO(First In First Out),故又称为先进先出的线性表。
队列的存储一般分为两种:顺序存储和链式存储。
队列的顺序实现是指分配一块连续的的存储单元存放队列中的元素,并附设两个指针front和rear分别指示队头元素和队尾元素的位置。
队列的顺序存储类型描述:
#define MaxSize 100
typedef struct SqQueue{
ElemType data[MaxSize]; //存放队列元素
int front,rear; //队头指针和队尾指针
}SqQueue;
队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表,头指针指向队头结点,尾指针指向对为节点,即单链表的最后一个结点。
队列的链式存储类型描述:
typedef struct LinkNode{ //链式队列结点
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct LinkQueue{ //链式队列
LinkNode *front,*rear; //队列的队头和队尾指针
}LinkQueue;
队列常见的基本操作包括:
说明:队头指针指向队头元素,队尾指针指向队尾元素的下一个位置。
下图为一个元素最大个数为5的队列的队列操作情况。
但是,这样存在一个很大的问题,就是怎么判断队满?能否用rear=MaxSize作为队列满的条件呢?答案是否定的。由(d)可以看出,此时rear=MaxSize=5,但数组中仍然存在可以存放元素的空位置,因为原先入队的元素出队了,所以是一种假溢出。故引入了循环队列,在下面的内容中给出。
循环队列是将队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列。
当队首指针front=MaxSize-1后,再前进一个位置就自动到0,通过除法取余运算%来实现。
1. 初始化
//初始化
void InitQueue(SqQueue &Q){ //初始化队首、队尾指针
Q.front = Q.rear = 0;
}
2. 判空操作
如上图所示,队空和队满时都由Q.front==Q.rear,为了区分是队空还是队满的情况,有三种处理方式:
//判空操作,采用第一种方式
bool Empty(SqQueue Q){
if(Q.rear==Q.front)return true;
else return false;
}
3. 入队
//入队
void EnQueue(SqQueue &Q, int x){
if((Q.rear+1)%MaxSize == Q.front)return; //队满
Q.data[Q.rear] = x;
Q.rear = (Q.rear+1)%MaxSize;
}
4. 出队
//出队
void DeQueue(SqQueue &Q, int &x){
if(Q.front==Q.rear)return;//空队
x = Q.data[Q.front];
Q.front = (Q.front+1)%MaxSize;
}
5. 读取队首元素
//读取队首元素
int GetElem(SqQueue Q){
return Q.data[Q.front];
}
1. 初始化
//初始化
void InitQueue(LinkQueue &Q){
Q.front = (LinkNode*)malloc(sizeof(LinkNode)); //建立头结点
Q.front->next = NULL; //初始为空
Q.rear = Q.front;
}
2. 判空操作
//判空
bool Empty(LinkQueue Q){
if(Q.front==Q.rear) return true;
else return false;
}
3. 入队
//入队
void EnQueue(LinkQueue &Q, int x){
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
}
4. 出队
void DeQueue(LinkQueue &Q, int &x){
if(Q.front==Q.rear)return;//空队
LinkNode *p = Q.front->next;
x = p->data;
Q.front->next = p->next;
if(Q.rear==p){
Q.rear = Q.front; //若原队列中只有一个结点,删除后变空
}
free(p);
}
5. 读取队首元素
//读取队首元素
int GetElem(LinkQueue Q){
return Q.front->next->data;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。