队列(queue)是一种运算受限的线性表,仅允许在表的一端进行插入,而在表的另一端进行删除。进行插入的一端叫做队尾,进行删除的一端叫做队头。
队列的操作:
向队列中插入新元素称为进队或入队,新元素进队后就成为新的队尾元素
从队列中删除元素称为出队或离队,元素出队后,其后继元素就成为队首元素
从队列的基本概念和操作来看,队列是一种具有先进先出特点的数据结构。
假设队列中有n个元素,其中a1是队头元素,an为队尾元素,那么在删除元素时就可以从a1开始,在插入新元素时就可以从an后面进行插入。
ADT Queue
{
数据对象:
D = {ai | ai∈ElemType, i=1,2,…,n, n≧0 } //ElemType为类型标识符
数据关系:
R = {1> | ai, ai+1∈D, i=1,3,…,n-1 }
数据操作:
InitQueue(&q):初始化队列。构造一个空队列q。
DestroyQueue(&q):销毁队列。释放队列q占用的存储空间。
QueueEmpty(q):判断队列是否为空。若队列q为空,则返回真;否则返回假。
enQueue(&q,e):进队列。将元素e进队作为队尾元素。
deQueue(&q,&e):出队列。从队列q中出队一个元素,并将其值赋给e。
}
对于队列的顺序存储结构来说,队列中的数据元素data都是具有同一数据类型(ElemType),通过MaxSize我们可以确定队列的存储空间,可以利用顺序存储结构把这些数据元素data保存下来,当操作队列时同时还需要关注队首(front)和队尾(rear)。
定义队列的存储结构:
typedef struct
{
ElemType data[MaxSize]; //定义数组存储空间
int front; //队首指针
int rear; //队尾指针
} SqQueue;
在队列的四要素中,rear指向队尾元素,front指向队头元素的前一个位置:
1. 当初始化一个队列的时候,队列中的队首(front)和队尾(rear)应该指向-1,表示还没有指向有效位置
2. 当数据元素a,b,c,d按次序入队时,每次数据元素入队都是从队尾(rear)开始的,所以队尾(rear)的指向一直在增加,由于没有数据元素出队,队首(front)的指向还是-1。
3. 当数据元素出队时,总是在队首进行的,当数据元素a要出队时,队首(front)就应该指向数据元素a的位置。
4. 当队列中的所有数据元素都出队时,队首(front)会指向最后一个数据元素d的位置,此时队首和队尾的位置相同,队列为空。
队列四要素总结:
队空条件:front == rear
队满条件:rear == MaxSize-1
元素e进队:rear++ ; data[rear] == e
元素e出队:front++ ; e == data[front];
1.初始化队列InitQueue(q)
创建一个空队列q,将front和rear指针均初始化为-1值
void InitQueue(SqQueue *&q)
{
q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=-1;
q->rear=-1;
}
2.销毁队列DestroyQueue(q)
释放队列q占用的存储空间
void DestroyQueue(SqQueue *&q)
{
free(q);
}
3.队列是否为空QueueEmpty(q)
若队列q满足q->front==q->rear条件,则说明队列为空,否则不为空
bool QueueEmpty(SqQueue *q)
{
return(q->front==q->rear);
}
4.入队列enQueue(q,e)
在进行入队操作时,应该先判断队列是否已满。如果队列不满则将队尾(rear)+1,然后将元素入队
bool enQueue(SqQueue *&q,ElemType e)
{
if (q->rear==MaxSize-1)
return false;
q->rear++;
q->data[q->rear]=e;
return true;
}
5.出队列deQueue(q,e)
在进行出队操作时,也应该先判断队列是否已满,如果队列不满则将队首(front)+1,将该位置的元素值赋给e
bool deQueue(SqQueue *&q,ElemType &e)
{
if (q->front==q->rear)
return false;
q->front++;
e=q->data[q->front];
return true;
}
假设这么一种情况,队列的存储空间可以存储5个数据元素,在开始时,一直往队列中加入元素a,b,c,d,e,当队列满时,rear指向下标为4的位置,此时队列无法再加入新的元素。
当队列满时,就一直将队列中的元素全部出队,当最后一个元素e出队时,队列就为空,队首(front)也会指向下标为4的位置。
此时就会造成队尾(rear)和队首(front)指向同一位置,由于队首(front)指向了队列的末尾,说明队列为空,但是由于队尾(rear)也指向了队列的末尾,就会造成一种“队列已满”的假象
,但事实上并非如此,因此这将会造成队列空间的浪费。也就是说顺序队列可能会出现“队列已满”的假象,导致存储空间不足。