4. 队列(queue))

4.1 简介

  • 队列是先进先出(FIFO, First In, First Out)的线性表
  • 常由链表或数组实现:
  • 顺序队列:数组实现的队列
  • 链式队列:链表实现的对她
  • 队列只允许在后端(raer)进行插入操作(入队,enqueue);在前端(front)进行删除操作(出队,dequeue
  • 执行复杂度
  • 访问:O(n)
  • 插入/删除:O(1),后端插入前端删除

4.2 分类

4.2.1单队列

单队列就是常见队列,元素添加到队尾。分为顺序队列和链式队列。

  • ”假溢出”问题:顺序队列存在明明有位置却不能添加的情况

在进行入队和出队操作时,front和rear都会持续向后移动,当rear移动到最后时,无法添加数据(即使数组在最前还有空余空间)

  • “越界”问题:添加元素时,rear移动到数组之外

为了避免当只有一个元素的时候,队头和队尾重合使处理变得麻烦,所以引入两个指针,front 指针指向对头元素,rear 指针指向队列最后一个元素的下一个位置,这样当 front 等于 rear 时,此队列不是还剩一个元素,而是空队列。——From 《大话数据结构》

假溢出介绍

4.2.2 循环队列

循环队列可以解决假溢出和越界问题。

循环队列的rear移动到数组的最后时,下一次移动至数组下表为0

循环队列的 front=rear时循环队列可能为空也可能为满,解决方法:

  1. 可以设置一个标志变量 flag,当 front==rear 并且 flag=0 的时候队列为空,当 front==rear 并且 flag=1 的时候队列为满。
  2. 队列为空的时候就是 front==rear ,队列满的时候,我们保证数组还有一个空闲的位置,rear 就指向这个空闲位置,如下图所示,那么现在判断队列是否为满的条件就是: (rear+1) % QueueSize= front

4.3 常见应用场景

处理需要按一定顺序进行时

  • 阻塞队列:在队列基础上加入阻塞操作。队列为空时,出队阻塞;队列为满时,入队阻塞
  • 线程池中的请求/任务队列:线程池没有空闲线程时将请求放在队列中,有空闲时从队列中获取任务执行。
  • 无界队列(链表):一直入列,除非系统资源耗尽
  • 有界队列(数组):队列满后会拒绝请求
  • Linux内核进程队列(按优先级排列)
  • 播放列表
  • 消息队列
  • ……