function Heap(arr) {
this.arr = arr;
this.buildMaxHeap();
}
Heap.prototype.buildMaxHeap = function() {
const length = this.arr.length;
// 初始化大顶堆,从倒数第一个非叶子结点开始,一直到根节点
for (let i = Math.floor(length / 2 - 1); i >= 0; i--) {
// 执行shiftDown,就是让该子堆满足最大堆
this.maxHeapify(this.arr, i, length);
}
return this.arr;
}
// 该函数的作用是让每个子堆满足最大堆的要求
Heap.prototype.maxHeapify = function(arr, i, length) {
// 左子节点索引
let left = 2 * i + 1;
// 右子节点索引
let right = 2 * i + 2;
// 最大值索引(默认为父节点)
let largest = i;
// 若存在左节点,且比父节点大,则把左子节点索引和最大值索引交换,等后面交换值
if (left < length && arr[left] > arr[largest]) {
largest = left;
}
if (right < length && arr[right] > arr[largest]) {
largest = right;
}
// 如果i!=largest,说明父节点不是最大的,需要交换
if (i !== largest) {
swap(arr, i, largest);
// 交换完之后还要对子堆进行maxHeapify
this.maxHeapify(this.arr, largest, length);
}
}
Heap.prototype.sort = function() {
// 每次将最大的放在数组最后,然后长度-1,再对根节点进行堆化
let length = this.arr.length;
while (length >= 1) {
swap(this.arr, length - 1, 0);
this.maxHeapify(this.arr, 0, length - 1);
length--;
}
}
// 交换数组中两个数
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
参考博客:
https://www.jianshu.com/p/90bf2dcd6a7b