队列学习笔记
队列及其抽象数据类型
基本概念
队列是一种只允许在表的一端进行插入操作,而在另一端进行删除操作的线性表(先进先出表)。允许进行删除的这一段叫做队列的头,允许进行插入的这一端叫做队列的尾。当队列中没有任何元素时,称为空队列。队列的插入操作通常称为进队列或入队列,队列的删除操作通常称为退队列或出队列。
抽象数据类型
1 | ADT Queue is |
队列的顺序表示
存储结构
1 | struct SeqQueue{/*顺序队列类型定义*/ |
假设paqu
是PSeqQueue
类型的变量,则:
paqu->f
存放即将要被删除的元素的下标paqu->r
存放即将要被插入的元素的下标paqu->q[paqu->f]
表示当前队列头部的元素paqu->q[paqu->r]
表示当前队列尾部的(即将插入的)的元素- 初始时
paqu->f=paqu->r=0
- 当前队列中元素个数为
paqu->r-paqu->f
- 当
paqu->r=paqu->f
时,元素的个数为0,即为空队列。
队列溢出
在队列中,由于数组是静态结构,而队列是动态结构,可能出现队列溢出问题。当队列满时,再作进队操作,这种现象称为上溢,当对空时,作删除操作,这种现象称为下溢。
由于队列中经常要执行插入和删除运算,而每运行一次插入或删除,paqu->r
或paqu->f
就增加1,使得队列中的元素被删除后,其空间就永远使用不到了,当paqu->r=MAXNUM
时,再作插入运算就会产生溢出,而实际上这时队列的前端可能还有许多可用的位置,因此,这种现象称为假溢出。
环形队列
解决假溢出通常采用的方法是:把数组paqu->q[MAXNUM]
从逻辑上看成一个环,这种队列也成为环形队列。当表中已有MAXNUM-1
个节点时,如果还要插入,paqu->r
和paqu->f
就会重合,这与空队列的情形相同,为了区分空队列与满队列两种情况的环形队列,一般是牺牲队列中的一个节点,当的队列中已有MAXNUM-1
个节点时就称为满,再要插入就发生溢出。
基本运算的实现
创建一个空队列
1 | /*创建一个空队列*/ |
判断队列是否为空
1 | /*判队列是否为空队列*/ |
进队运算
1 | void enQueue_seq(PSeqQueue paqu, DataType x) |
出队运算
1 | void deQueue_seq(PSeqQueue paqu) |
取队列头部元素运算
1 | DataType fromtQueue_seq(PSeqQueue paqu) |
队列的链接表示
存储结构
队列的链接表示就是用一个单链表来表示队列,队列中的每个元素对应链表中的一个结点,结点的结构与单链表中结点的结构一样。为了强调队头和队尾都是队列的属性,对队列增加了一层封裝,引入 LinkQueue
结构的定义。这样存储的队列简称链接队列。
1 | struct Node; |
假设plqu
是PLinkQueue
类型的变量,则:
plqu->f
为队列的头指针,指向队列中第一个节点plqu->r
是队列的尾指针,指向队列中最后一个节点- 当
plqu->f
或plqu->r
为NULL时队列为空
基本运算的实现
创建空队列
1 | PLinkQueue createEmptyQueue_link(void){ |
判断队列是否为空
1 | int isEmptyQueue_link(PLinkQueue plqu){ |
进队列运算
1 | void enQueue_link(PLinkQueue plqu,DataType x){ |
出队列运算
1 | void deQueue_link(PLinkQueue plqu){ |
取队列头部元素的值
1 | DataType frontQueue_link(PLinkQueue plqu){ |