第3章 队列

Chap3.4 队列

chap3.4.1 队列及其基本概念

一、队列的基本概念

  • 队列(Queue):也是运算受限的线性表。是一种先进先出(First In First Out ,简称FIFO)的线性表。只允许在表的一端进行插入,而在另一端进行删除。
  • 队首(front) :允许进行删除的一端称为队首。
  • 队尾(rear) :允许进行插入的一端称为队尾。

例如:排队购物。操作系统中的作业排队。先进入队列的成员总是先离开队列。

队列中没有元素时称为空队列。在空队列中依次加入元素a1, a2, …, an之后,a1是队首元素,an是队尾元素。显然退出队列的次序也只能是a1, a2, …, an ,即队列的修改是依先进先出的原则进行的,如图所示。
在这里插入图片描述

二、队列的抽象数据类型定义

在这里插入图片描述

chap3.4.2 队列的顺序表示和实现

利用一组连续的存储单元(一维数组) 依次存放从队首到队尾的各个元素,称为顺序队列。
对于队列,和顺序栈相类似,也有动态和静态之分。
静态顺序队列,其类型定义如下:

#define  MAX_QUEUE_SIZE   100
typedef  struct  queue
{  ElemType   Queue_array[MAX_QUEUE_SIZE] ;
int   front ;
int  rear ;
}SqQueue;

一、队列的顺序存储结构

设立一个队首指针front ,一个队尾指针rear ,分别指向队首和队尾元素。
◆ 初始化:front=rear=0。
◆ 入队:将新元素插入rear所指的位置,然后rear加1。
◆ 出队:删去front所指的元素,然后加1并返回被删元素。
◆ 队列为空:front=rear。
◆ 队满:rear=MAX_QUEUE_SIZE-1或front=rear。

在非空队列里,队首指针始终指向队头元素,而队尾指针始终指向队尾元素的下一位置。
顺序队列中存在“假溢出”现象。因为在入队和出队操作中,头、尾指针只增加不减小,致使被删除元素的空间永远无法重新利用。因此,尽管队列中实际元素个数可能远远小于数组大小,但可能由于尾指针巳超出向量空间的上界而不能做入队操作。该现象称为假溢出。如图3-6所示是数组大小为5的顺序队列中队首、队尾指针和队列中元素的变化情况。在这里插入图片描述

二、循环队列

为充分利用向量空间,克服上述“假溢出”现象的方法是:将为队列分配的向量空间看成为一个首尾相接的圆环,并称这种队列为循环队列(Circular Queue)
在这里插入图片描述

在循环队列中进行出队、入队操作时,队首、队尾指针仍要加1,朝前移动。只不过当队首、队尾指针指向向量上界(MAX_QUEUE_SIZE-1)时,其加1操作的结果是指向向量的下界0。

这种循环意义下的加1操作可以描述为:
if (i+1==MAX_QUEUE_SIZE) i=0;
else i++ ;
其中: i代表队首指针(front)或队尾指针(rear)

用模运算可简化为:i=(i+1)%MAX_QUEUE_SIZE ;

显然,为循环队列所分配的空间可以被充分利用,除非向量空间真的被队列元素全部占用,否则不会上溢。因此,真正实用的顺序队列是循环队列。
例:设有循环队列QU[0,5],其初始状态是front=rear=0,各种操作后队列的头、尾指针的状态变化情况如下图所示。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针,故队空和队满时头尾指针均相等。因此,无法通过front=rear来判断队列“空”还是“满”。解决此问题的方法是:约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满。即:
◆ rear所指的单元始终为空。
◆ 循环队列为空:front==rear 。
◆ 循环队列满:(rear+1)%MAX_QUEUE_SIZE ==front。

—> 循环队列 CylSeqQueue

chap3.4.3 队列的链式表示和实现

一、队列的链式存储结构

队列的链式存储结构简称为链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。

需要两类不同的结点:数据元素结点,队列的队首指针和队尾指针的结点,如图所示。
在这里插入图片描述
数据元素结点类型定义:

typedef struct Qnode
{  ElemType    data ;
struct Qnode  *next ;
}QNode ;

指针结点类型定义:

typedef struct link_queue
{   QNode  *front ,  *rear ;
}Link_Queue ;

二、链队运算及指针变化

链队的操作实际上是单链表的操作,只不过是删除在表头进行,插入在表尾进行。插入、删除时分别修改不同的指针。链队运算及指针变化如图所示。
在这里插入图片描述
在这里插入图片描述
—> 链队 LinkQueue

—> 模拟银行排队 BankQueuing <—

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/87863047