风也温柔

计算机科学知识库

多任务下的数据结构与算法 数据结构和算法-线性结构-队列

  队列认识队列

  受限的线性结构:

  队列(Queue)多任务下的数据结构与算法 数据结构和算法-线性结构-队列,它是一种受限的线性表多任务下的数据结构与算法,先进先出(FIFO First In First Out)

  保结构加倍算法_并行计算——结构·算法·编程_多任务下的数据结构与算法

  image-生活中的队列

  生活中类似的队列结构

  并行计算——结构·算法·编程_多任务下的数据结构与算法_保结构加倍算法

  image-开发中队列的应用

  打印队列:

  线程队列:

  当然队列还有很多其他应用,我们后续的很多算法中也会用到队列(比如二叉树的层序遍历)。

  队列如何实现呢?

  队列的实现队列类的创建

  队列的实现和栈一样,有两种方案:

  我们需要创建自己的类,来表示一个队列

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;">class Queue {   private data: T[] = []; } </pre>

  代码解析:

  队列的常见操作

  队列有哪些常见的操作呢?

  实现队列的接口

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> interface IQueue {    // 入队方法    enqueue(element: T): void    // 出队方法    dequeue(): T | undefined    // peek    peek(): T | undefined    // 判断是否为空    isEmpty(): boolean    // 元素的个数    size(): number  }    export default IQueue </pre>

  实现队列

  现在,我们来实现这些方法。

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> import IQueue from './IQueue'    class ArrayQueue implements IQueue {    private data: T[] = []      enqueue(element: T): void {      this.data.push(element)    }    dequeue(): T | undefined {      return this.data.shift()    }    peek(): T | undefined {      return this.data[0]    }    isEmpty(): boolean {      return this.data.length === 0    }    size(): number {      return this.data.length    }  }    export default ArrayQueue   </pre>

  List接口封装和继承关系

  我们发现我们定义的栈接口和队列接口,都有相同的操作方法 peek, 和 size。

  可以将这些抽取成接口,让栈和队列的接口继承。

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> export default interface IList {    // peek    peek(): T | undefined    // 判断是否为空    isEmpty(): boolean    // 元素的个数    size(): number  } </pre>

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> import IList from '../types/IList'    // 定义栈的接口  interface IStack extends IList {    push(element: T): void    pop(): T | undefined  }  export default IStack </pre>

  <pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> import IList from '../types/IList'    interface IQueue extends IList {    // 入队方法    enqueue(element: T): void    // 出队方法    dequeue(): T | undefined  }  export default IQueue </pre>

  队列面试题击鼓传花

  击鼓传花 是一个常见的面试算法题:使用队列可以非常方便的实现最终的结果。

  原游戏规则:

  修改游戏规则:

  封装一个基于队列的函数:

  击鼓传花的代码实现

  保结构加倍算法_多任务下的数据结构与算法_并行计算——结构·算法·编程

  img

<p><pre style="box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;margin-top: 10px;margin-right: auto;margin-left: auto;"> import ArrayQueue from './01_实现队列结构-数组'    function hotPotato(names: string[], num: number): number {    if (names.length === 0) return -1      // 1. 定义一个队列    const queue = new ArrayQueue()      // 2. 将数据放入到队列中    for (let i = 0; i  1) {      // 1/2 不淘汰      for (let i = 0; i