题目描述
构建一个小顶堆,支持添加、删除、获取堆顶元素
思路解析
每次添加元素时,都需要调整一下堆结构;
每一次删除最顶上面的元素也需要调整结构;
代码实现
function HeapNode(value) {
this.value = value;
}
class MinHeap {
constructor(value) {
this.heap = value !== undefined ? [new HeapNode(value)] : [];
}
push(value) {
this.heap.push(new HeapNode(value));
this.shitUp();
}
pop() {
if (!this.heap.length) {
return null;
}
const first = this.heap[0];
const last = this.heap.pop();
if (first !== last) {
this.heap[0] = last;
this.shitDown();
}
return first;
}
peek() {
return this.heap.length ? this.heap[0] : null;
}
shitUp() {
let index = this.heap.length - 1;
const heap = this.heap;
while (index > 0) {
// parent 对应 左右两个节点,例如[0, 1, 2] 2 的 parent 为 0, 故需要 index - 1
const parentIndex = (index - 1) >>> 1;
// 如果父节点更大,就调整一下
if (this.isGreater(heap[parentIndex], heap[index])) {
const temp = heap[parentIndex];
heap[parentIndex] = heap[index];
heap[index] = temp;
index = parentIndex;
} else {
return;
}
}
}
shitDown() {
const length = this.heap.length;
const halfLength = length >>> 1;
let index = 0;
const heap = this.heap;
while(index < halfLength) {
const leftIndex = (index + 1) * 2 - 1;
const leftNode = heap[leftIndex];
const rightIndex = leftIndex + 1;
const rightNode = heap[rightIndex];
const parentNode = heap[index];
// parent 比左边大
if (this.isGreater(parentNode, leftNode)) {
// 左边比右边的大
if (rightNode && this.isGreater(leftNode, rightNode)) {
heap[index] = rightNode;
heap[rightIndex] = parentNode;
index = rightIndex;
} else {
heap[index] = leftNode;
heap[leftIndex] = parentNode;
index = leftIndex;
}
} else if (rightNode && this.isGreater(parentNode, rightNode)) {
heap[index] = rightNode;
heap[rightIndex] = parentNode;
index = rightIndex;
} else {
return;
}
}
}
isGreater(target, source) {
return target.value > source.value;
}
}
// test case
// const heap = new MinHeap();
// const arr = [5, 2, 1, 9, 6, 7, 3, 4, 0, 8]
// for (let i of arr) {
// heap.push(i);
// }
// console.log(heap.heap.map(i => i.value).join(','));
// heap.pop();
// console.log(heap.heap.map(i => i.value).join(','));