Open
Description
class Heap {
constructor() {
this.data = [];
}
build(arr) {
this.data = [];
for (let i = 0; i < arr.length; i++) {
this.insert(arr[i]);
}
}
print() {
console.log(this.data);
}
insert(value) {
// 先把当前元素加到最后一个位置
this.data.push(value);
// 获取当前元素的index
let nIndex = this.data.length - 1;
// 获取父节点
let nParentIndex = Math.floor((nIndex - 1) / 2);
while (nParentIndex >= 0) {
// 当前节点大于父节点,则交换顺序
if (this.data[nIndex] > this.data[nParentIndex]) {
[this.data[nIndex], this.data[nParentIndex]] = [
this.data[nParentIndex],
this.data[nIndex],
];
}
// 当前父元素赋值为 nIndex
nIndex = nParentIndex;
// 获取再上一个父元素的下标
nParentIndex = Math.floor((nIndex - 1) / 2);
}
}
// 删除最大节点
delete() {
if (this.data.length <= 1) {
return (this.data = []);
}
// 把最后一个节点临时补到原本堆顶的位置
// 删除第一个节点,将最后一个子节点补充到根节点
this.data[0] = this.data.pop();
let len = this.data.length;
let curIndex = 0;
// 暂时处于堆顶位置的节点和它的左右孩子节点进行比较
while (curIndex < len) {
let nLeftIndex = 2 * curIndex + 1;
let nRightIndex = 2 * curIndex + 1;
let maxLeafIndex = nLeftIndex;
// 找到左右节点中较大的一个 nSelectIndex
if (nRightIndex < len) {
maxLeafIndex =
this.data[nLeftIndex] > this.data[nRightIndex] ? nLeftIndex : nRightIndex;
}
// 判断 maxLeafIndex 如果大于 curIndex, 则交换
if (maxLeafIndex < len && this.data[maxLeafIndex] > this.data[curIndex]) {
[this.data[maxLeafIndex], this.data[curIndex]] = [
this.data[curIndex],
this.data[maxLeafIndex],
];
}
curIndex = maxLeafIndex;
}
}
}
const heap = new Heap();
heap.build([1, 3, 4, 2]);
heap.print(); // [ 4, 2, 3, 1 ]
heap.delete();
heap.print(); // [ 3, 2, 1 ]