本系列文章主要学习“队列”这种数据结构的基本操作、实现方式、应用和扩展(双端队列)。其中,本文将介绍队列这种数据结构的特点和一种实现方式。
一、Queue(点击打开链接)
前面学习的Stack是在“pile”的同一端添加或删除元素,是一种FILO型的线性表;而Queue是在“pile”的一端添加元素,在“pile”的另一端删除元素,是一种FIFO型的线性表,如下图。
队列的基本操作就是“入队”和“出队”。基础类接口如下:
二、QueueAsArray
同Stack一样,Queue既可以用动态数组实现,也可以用链表实现。先看它的数组实现:
用数组来实现的队列,它包含了三个成员:head、tail和array。其中array就是存放元素指针的数组,而head和tail是数组元素的两个跟踪index。事实上,还有一个成员继承自“Container”,即“count”,元素计数。
关于这三个int型成员的关系,如下:
图a表示,一般情况下,head表示队列最左端元素的下标,tail表示队列最右端元素的下标。“count = tail - head + 1”。
图b演示某些情况下,tail和head都增长,出现交叉(生成者 vs. 消费者)
图c表示只有一个数组元素的情况,“head = tail”,注意元素的实际位置可以在数组的任一位置。
图d展示了一种判断空队列的方法,“head越过了tail”。
注:
1)这是一个固定长度的队列,队列的size即数组的size。观察Enqueue和Dequeue的实现代码,它们分别对tail和head与数组长度进行比较,如果相等,则清零。
2)head和tail只进行++运算。这样,也就很容易出现图b所示的情况。故,对队列来说左右两端是不交叉的,而它的实现数组是可以交叉的。
3)Stack只有一个成员,即count,它可以++,也可以--运算。