队列

队列和栈一样,都是一种对数据的“插入”和“删除”有特殊要求的线性表

队列是什么

  • 什么是队列?

只能在表的一端进行插入,另一端进行进行删除,且操作具有先进先出的原则的线性表成为队列

[数据结构]-06队列

  • 什么是队头、队尾?
    数据只能在队列的一端插入,另一端删除,所以:
    • 队列中进行删除的一端称为队头
    • 队列中进行插入的一端称为队尾

若用 S=(a1,a2,a3,...,an)S=(a_1,a_2,a_3,...,a_n) 表示队列,则:
 - a1a_1 称为队头元素;
 - ana_n 称为队尾元素;
 - 没有元素的队列称为空队列

  • 什么是入队、出队?
    因为队列操作的特殊性,队列常见的两种操作:

    • 插入数据到队尾的操作称为入队
    • 从队头删除第一个元素的操作称为出队
  • 队列的先进先出原则

    • 先入队的元素在队头,最后入队的元素在队尾。
    • 删除元素时最先入队的元素先出队,最后入队的元素最后出队。
  • 什么是双端队列?

限定插入和删除操作在表的两端进行的线性表称为双端队列
[数据结构]-06队列

  • 双端队列的演变
    • 输出受限的双端队列,一个端点只允许插入和删除,另一个端点只允许插入。
    • 输入受限的双端队列,一个端点只允许插入和删除,另一个端点只允许删除。
    • 双端队列也可以退化成栈,即只能在一端进行插入和删除。

队列基本操作

  • 向队尾添加元素(入队)
  • 删除队首元素(出队)
  • 获取队首的元素值(存取)
  • 判断队列是否为满
  • 判断队列是否为空

顺序队列

  • 什么是顺序队列?

用顺序存储方式存储的队列称为顺序队列

  • 元素出队时队头元素如何处理?
    元素入队只要将元素添加到队列的最后一个位置即可,但元素出队时在顺序队列中队头元素的位置是否变化,分两种情况讨论:
    • 元素出队后,新的队头元素不要求必须放在存储空间的第一个位置。元素出队后,只需将下一个元素设置成新的队头即可。
      • 优点:不会改变队列中其他元素地址;
      • 缺点:随着元素的出队,队列的队头的存储位置后移,可能出现存储空间不足,新元素无法入队,而队头前端大量存储空间被闲置,造成空间的浪费。
    • 元素出队后,新队的队头元素必须存放在存储空间的第一个位置。元素出队后,所有元素向前移动一个位置。
      • 优点:有效的利用了存储空间;
      • 缺点:所有元素存储位置都要改变,时间效率低。

出于对空间和时间效率的考虑,暂时牺牲空间换取时间,通常队列操作采用方式 1。

  • 队列指针的设置及队空判断
    根据队列出队和入队的特点,队列设置两个指针分别指向队头和队尾:
    • frontfront 指针为队头指针,指示队头元素在顺序队列中的位置
    • rearrear 指针为队尾指针,指示队尾元素的下一个位置,初始值指向队头:front==rearfront == rear
    • maxSizemaxSize 表示队列的存储空间大小
    • front==rearfront == rear队空,当 front==maxSizefront == maxSize队列溢出,不能再添加元素

顺序队列的初始化

  • 为顺序队列分配初始存储空间 maxSizemaxSize,使 frontfront 指向空间的基地址。
  • front==rearfront == rear

顺序队列的入队

  • 判断队列是否溢出,若溢出不能再添加元素
  • 否则将新元素入队,队尾指针加 1:rear=rear+1rear = rear + 1

顺序队列之出队

  • 判断队列是否为空,若队空则不能删除元素
  • 否则队头元素出队,队头指针加 1:front=front+1front = front + 1

循环队列

为了解决顺序队列元素出队时造成的存储空间浪费,可以假定顺序队列是一个封闭的环,提升运算效率与空间效率之间的矛盾

  • 什么是循环队列?

将队头与队尾连接形成闭环的队列城为循环队列

[数据结构]-06队列

  • 队列指针
    循环队列与顺序队列一样,设置队头指针 frontfront 和队尾指针 rearrear

    • 元素出队,frontfront 顺时针移动一个位置;
    • 元素入队,rearrear 顺时针移动一个位置。
  • 队满的争议?
    与顺序队列的溢出不同,循环队列队满时便不能再添加新的元素,若 frontfrontrearrear 指针的定义与顺序队列中相同,则出现 front==rearfront == rear 时无法判断队列是满还是空的情况,所以如何判断队满?

    • 新增变量 countcount 标识队列元素个数,当 count==maxSizecount == maxSize 时为队满;当 count=0count = 0 时队空。
    • 循环队列少用一个元素,当队头指针在队尾指针的下一个位置时,队列为满,队列元素为 maxSize1maxSize - 1;当 front==rearfront == rear 时队空。

为了操作的便捷性,通常采用方式 2 判断队空队满,以下循环队列的操作以方式 2 为基准。

  • 如何判断队空队满?
    循环队列的 frontfrontrearrear 指针的定义与顺序队列中相同,队空队满及队列元素个数判断如下:
    • (rear+1)%maxSize==front( rear + 1 ) \% maxSize == front 时队满;
    • front==rearfront == rear 时队空;
    • 队列中有效元素个数:(rear+maxSizefront)%maxSize(rear + maxSize - front) \% maxSize

循环队列的初始化

  • 为循环队列分配初始存储空间 maxSizemaxSize,使 frontfront 指向空间的基地址。
  • front==rearfront == rear

循环队列有效长度

  • 循环队列的有效长度:(rear+maxSizefront)%maxSize(rear + maxSize - front) \% maxSize

循环队列的入队

  • 判断循环队列是否为满:(rear+1)%maxSize==front( rear + 1 ) \% maxSize == front ,若队满则不能添加新元素
  • 否则将新元素入队,队尾指针加 1:rear=(rear+1)%maxSizerear = (rear + 1) \% maxSize

循环队列之出队

  • 判断队列是否为空:front==rearfront == rear,若队空则不能再删除元素
  • 否则队头元素出队,队头指针加 1:front=(front+1)%maxSizefront = (front + 1) \% maxSize

链式队列

  • 什么是链式队列?

用链接存储方式实现的队列称为链式队列

[数据结构]-06队列

  • 链式队列的指针
    链式队列添加头结点,使头指针指向头结点,同时增设两个指针:
    • 设队头指针 frontfront ,始终指向头结点
    • 设队尾指针 rearrear ,指向队尾结点,初始化时 front==rearfront == rear指向头结点

链式队列的初始化

操作步骤如下:

  • 创建一个新结点作为链式队列的头结点,并将队头和队尾指针指向头结点
  • 头结点的指针域为 nullnull

链式队列的入队

链式队列的入队就是将数据元素插入到队尾,具体操作如下:

  • 创建指针域为 nullnull 的新结点 pp
  • 将新结点插入到队尾结点之后,修改队尾结点指针域:rear.next=prear.next = p
  • 修改队尾指针:rear=prear = p

链式队列之出队

链式队列的出队就是删除链表的首元结点,具体操作如下:

  • 判断队列是否为空,若为空则不能删除结点
  • 否则获取首元结点 pp 的数据域
  • 进行删除首元结点操作,修改队头指针指向下一个结点:front.next=p.nextfront.next = p.next
  • 元素出队后再次判断队列是否为空,若为空将队尾指针指向头结点:rear=frontrear = front
  • 释放结点 pp

[数据结构]-06队列

循环队列和链式队列的比较

  • 时间复杂度

    • 循环队列和链式队列入队和出队的时间复杂度都为 O(1)O(1)
  • 空间上复杂度

    • 循环队列初始化时必须申请存储空间,队列的有效长度受限,在操作过程中队列的有效元素个数小于存储空间大小,所以造成空间浪费。
    • 链式队列存储过程中需要一个指针域,会产生空间上的开销,但队列元素个数不会受限制。

顺序队列与链式队列的比较

  • 顺序队列有固定的存储空间,不适用于存储空间很大,删除插入很频繁的操作,此时顺序队列的空间利用率很低;反之,链式队列适用此情况。
  • 顺序队列的访问简单,对队列内部元素的访问便捷;链式队列元素需便利整个链表。

应用实例

  • 银行拿号排队问题

参考资料:
[1] 《数据结构(C语言版)》 严魏敏、吴伟民著
[2] 《数据结构(第3版)》 刘大有等著

相关文章: