9.顶堆结构js实现

61 阅读1分钟

不多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]