08.优先队列

一、 什么是优先队列

如果有这样一个数据流 1,2,3,4,5,6,7,8 我们需要按照一定的优先级找到满足条件(最大或者最小)的元素,并且每次取出最高优先级的元素后,内部元素依旧能够按照既定优先级保证最高优先级的元素在顶端。

二、 最大堆 & 最小堆

  • 分为 最大堆最小堆 ,其实就是 完全二叉树

    • 最大堆

      • 要求节点的元素都要大于等于其孩子

    • 最小堆

      • 要求节点元素都小于等于其左右孩子

  • 两者对左右孩子的大小关系不做任何要求

为什么用 二叉树 来实现呢?

如果使用数组复杂度会更高

三、 插入元素

如下数据流,我们按照顺序插入数据,并且每次返回最大的元素,我们就可以使用优先队列(最大堆)。

步骤1

  • 插入 1 和 5 ,如图二叉树结构

  • 叶子节点 5 > 1 ,不符合优先级规则,需要交换位置

  • 等价数组为

    • [5, 1]

1

步骤2

  • 插入 6

    • 每次插入都插入到当前最深层从左往右的位置,或者创建下一层

  • 6 大于父节点 5,需要调整位置

  • 交换 5 6

  • 等价数组为

    • [6, 1, 5]

2

步骤3

  • 插入 2

    • 这一层满了,下一层最左边

  • 2 大于父节点 1,需要调整

  • 交换 2 1

  • 等价数组为

    • [6, 2, 5, 1]

3

步骤4

  • 插入 7

  • 7 大于父节点 2,需要调整

  • 交换 7 2

    • 7 的父节点变为 6,还需要调整

    • 交换 7 6

  • 等价数组为

    • [7, 6, 5, 1, 2]

4

步骤5

  • 插入 4,父节点为 5,无需调整

  • 等价数组为

    • [7, 6, 5, 1, 2, 4]

5

步骤6

  • 插入 3,父节点为 5,无需调整

  • 等价数组为

    • [7, 6, 5, 1, 2, 4, 3]

6

步骤7

  • 插入 8

    • 下一层

  • 大于父节点 1,交换

  • 大于父节点 6,交换

  • 大于父节点 7,交换

  • 等价数组为

    • [8, 7, 5, 6, 2, 4, 3, 1]

7

插入代码实现

基础数据结构

插入逻辑

四、 移除元素

我们还以上面完成的 优先队列 数据结构为例,继续对移除元素的操作进行研究。

  • 这里我们计划移除 5 元素(当前下表为A)

  • 现将其和尾部元素交换

  • 移除尾部元素

  • 检查 A 处元素是否需要爬升

      • 将其上浮

        • 此处 A 元素为 1,小于父节点 8,无需处理

  • 检查 A 处元素是否需要下沉

      • 将其下降

        • 此处 A 元素为 1,小于子节点,进行下沉处理

8

移除与下沉逻辑实现

Swift 完整实现

下面的优先队列实现是参考 RxSwift 中的

Last updated

Was this helpful?