数据结构

优先队列(最小堆)

优先队列让你总能 O(log n) 拿到当前最小值。最常见的实现是二叉堆——一棵”父节点不大于子节点”的完全二叉树,正好可以用一个数组紧凑存储。

数组与树的关系

节点 i 的:

  • 父节点:(i - 1) >> 1
  • 左子:2i + 1
  • 右子:2i + 2

数组就是树的”层序遍历”。这就是为什么动画里数组的方块和树里的节点是同一个元素——它们是同一份数据的两种表示。

两个核心操作

insert(v):把 v 加到数组末尾(树的最后一个叶子位置),然后上浮:只要比父小就交换,直到父更小或自己成为根。

extractMin():根就是最小值。把它取出后,把数组末尾元素挪到根,然后下沉:与两个孩子中较小的比较,逆序就交换,直到不再违反堆性质。

每次操作最多走树的高度,约 ⌈log₂ n⌉ 步。

复杂度

  • insert / extractMin:O(log n)
  • peek:O(1)
  • 空间:O(n)

试试看

可视化上方有输入框:随便输个数字按”插入”,看上浮过程;按”弹出最小值”看下沉过程。整个操作序列每次变化都会从头重放,方便你来回比对。

在动画里看什么

  • 蓝色:正在比较的父子对(同时高亮连线)
  • 红色:发生交换的两个节点
  • 紫色:当前焦点(刚插入或刚成为新根)
  • 数组与树两个视图里的同一个值是同一个元素——交换发生时两边同步变化