// 添加元素 add(el){ if(this.size >= this.heap.length) return -1 // 往尾部插入元素后进行上浮操作 this.heap[0] += 1 this.heap[this.size] = el this.up() return el }
上浮
将节点与其父节点进行比较,如果不满足堆条件则和父节点交换,直到满足条件
1 2 3 4 5 6 7 8 9
up(){ let i = this.size let j = helper.parent(i) while (this.handle(i, j) && i > 1){ helper.swap(this.heap, i, j) i = j j = helper.parent(i) } }
弹出元素
将堆顶元素删除,把最后一个节点复制到堆顶,然后将堆顶元素执行下沉操作
1 2 3 4 5 6 7 8 9 10 11
// 弹出元素 pop(){ if(!this.size) return -1 // 弹出堆顶后将最后一个元素放置到堆顶,然后执行下沉操作 let el = this.peek() helper.swap(this.heap, 1, this.size) this.heap[this.size] = undefined this.heap[0] -= 1 this.down() return el }
下沉
将节点与子节点比较,与较小/较大的节点交换,直到满足条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
down(){ let i = 1 while(i < this.size && i <= this.size / 2){ // 获取左右孩子下标 let l = helper.left(i) let r = helper.right(i) if(this.handle(r, i) || this.handle(l, i)){ // 如果有一个不满足,则进入判断 let j = this.handle(r, l) ? r : l helper.swap(this.heap, i, j) i = j }else{ // 找到合适位置,跳出 break } } }