功能说明
MinHeap 是一个基于数组的二叉最小堆,支持任意类型元素和自定义比较器。push 把元素放到数组末尾后向上冒泡,pop 取出堆顶后用末尾元素下沉修复堆序,peek 以 O(1) 查看堆顶。它适合任务调度、合并有序流、Dijkstra 最短路和 Top-K 统计等需要反复取最小值的场景。
默认比较器按数值升序排列;传入返回负数的比较器即可定义“最小”的含义,例如按优先级和提交顺序排序的任务对象。from 静态方法可以批量构建堆。实现只使用私有字段,不依赖任何第三方库。
关键代码
入堆时不断与父节点比较,若当前元素更小则交换;出堆时把最后一个元素放到堆顶,再与较小的子节点交换直到恢复堆序。
push(value) {
this.#items.push(value);
this.#bubbleUp(this.#items.length - 1);
return this;
}
pop() {
if (this.#items.length === 0) return undefined;
const root = this.#items[0];
const last = this.#items.pop();
if (this.#items.length > 0) {
this.#items[0] = last;
this.#sinkDown(0);
}
return root;
}
使用注意
比较器必须满足全序关系并保持稳定,否则堆序可能被破坏;默认比较器只适用于可直接相减的数值,字符串应传入 localeCompare 或自定义比较。堆中允许重复元素,peek 和 pop 在空堆上返回 undefined,因此不能区分“存储了 undefined”和“堆为空”。
from 会逐个插入元素,时间复杂度为 O(n log n),而不是线性建堆;对性能敏感的大批量数据可以改成从中间向前下沉。堆不是稳定排序结构,相同优先级的元素出队顺序由比较器决定,示例通过附加递增序号来保证先进先出。修改已入堆对象的排序字段会破坏堆序,需要重新入堆。
验证方式
示例把四个任务按不同优先级加入堆,出队顺序应为 charge-card、send-email、warm-cache、rotate-logs,其中同优先级的两个任务按 sequence 保持先后。随后用 MinHeap.from([5, 1, 4, 2, 3]) 逐个弹出,输出 1,2,3,4,5,验证基本堆序和批量构建。