堆是在节点上存储数据的完全二叉树, 小顶堆是把对中最小值一直保持在堆顶的树型结构。其中主要通过替换父子节点来实现
- 向上筛选: 将新的值插入到堆尾,并通过与父节点(循环)比较来对换位置。
 
- 向下筛选: 将堆尾放入到已弹出的堆顶部,通过与子节点(循环)比较来对换位置。
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
   | class PriorityQue {   constructor(heap = []) {     this.heap = heap     this.build()   }
    getSize() {     return this.heap.length   }
    upward(i) {               while (this._parent(i) >= 0 && i > 0) {       if (this.heap[this._parent(i)] > this.heap[i]) {         let tmp = this.heap[i]         this.heap[i] = this.heap[this._parent(i)]         this.heap[this._parent(i)] = tmp       }       i = this._parent(i)     }   }
    downward(i) {          while (i * 2 <= this.getSize()) {       let idx = this.minChild(i)
        if (this.heap[i] > this.heap[idx]) {         let tmp = this.heap[idx]         this.heap[idx] = this.heap[i]         this.heap[i] = tmp       }       i = idx > 0 ? idx : 1     }   }
    minChild(i) {          let left_idx = i * 2     let right_idx = i * 2 + 1     if (right_idx > this.getSize()) {       return left_idx     } else if (this.heap[left_idx] < this.heap[right_idx]) {       return left_idx     } else {       return right_idx     }   }
    _parent(i) {          return Math.floor(i / 2)   }
    enqueue(e) {          this.heap.push(e)     this.upward(this.getSize())   }
    dequeue() {          let e = this.heap[0]     this.heap[0] = this.heap[this.getSize() - 1]     this.heap.pop()     this.downward(0)     return e   }
    build() {     let i = this.getSize()     while (i > 0) {       this.upward(i)       i -= 1     }   } }
  let q = new PriorityQue([5, 4, 3, 2, 1]) console.log(q) for (let i = 0; i < 5; i++) {   q.dequeue() }
  |