不多bb,上代码
class Heap {
constructor(compareFn) {
this.queue = []
this.compareFn = compareFn // 传入的比较函数
}
push(item) {
this.queue.push(item)
let idx = this.size() - 1 // 初始插入下标
let parent = idx - 1 >> 1 // 父下标
while (parent >= 0 && this.compare(parent, idx) > 0) { // 自底向上冒泡 p>i
[this.queue[parent], this.queue[idx]] = [this.queue[idx], this.queue[parent]];
idx = parent
parent = idx - 1 >> 1
}
}
pop() {
let top = this.queue[0] // 待移除的堆顶元素
this.queue[0] = this.queue.pop() // 堆底元素放堆顶
let idx = 0 // 初始父下标
let child = this.compare(2 * idx + 1, 2 * idx + 2) > 0 ? 2 * idx + 2 : 2 * idx + 1 // 子元素下标 2*idx+1 > 2*idx+2
while (child < this.size() && this.compare(idx, child) > 0) { // 自顶向下冒泡 i>c
[this.queue[child], this.queue[idx]] = [this.queue[idx], this.queue[child]];
idx = child
child = this.compare(2 * idx + 1, 2 * idx + 2) > 0 ? 2 * idx + 2 : 2 * idx + 1
}
return top
}
compare(idx1, idx2) {
// 结合调用示例new Heap((a,b)=>a-b)创建小顶堆来理解比较好一些
return this.compareFn(this.queue[idx1], this.queue[idx2])
}
size() {
return this.queue.length
}
}
调用示例
// 用小顶堆实现排序
let arr = [5, 2, 4, 8, 1, 6, 3, 7, 9, 10]
let heap = new Heap((a, b) => a - b)
for (let i = 0; i < arr.length; i++) heap.push(arr[i])
for (let i = 0; i < arr.length; i++) arr[i] = heap.pop()
console.log(arr) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]