# 堆排序(Heap Sort)
提示
数据结构——堆 堆:实际上可以理解为是一个完全二叉树的数组对象。
最大堆:堆中的某个节点的值必须不大于其父节点的值,堆总是一颗完全二叉树。
最小堆:堆中的某个节点的值必须不小于其父节点的值,堆总是一颗完全二叉树。
普通队列:先进先出,后进后出。(本质就是由时间的顺序决定出队顺序)。
优先队列:出队顺序和入队顺序无关,和优先级有关。处理【动态】任务。
实现优先队列最好的方式是是用堆这种数据结构。
class MaxHeap {
// constructor(capacity) {
// this.data = new Array(capacity + 1);
// this.count = 0;
// }
constructor(arr, length) {
this.data = new Array(length + 1);
for (let i = 0; i < arr.length; i++) {
this.data[i + 1] = arr[i];
}
this.count = length;
for (let k = Math.floor(this.count / 2); k >= 1; k--) {
this.shiftDown(k);
}
}
getSize() {
return this.count;
}
isEmpty() {
return this.count === 0;
}
insert(value) {
this.data[this.count + 1] = value;
this.count++;
this.shiftUp(this.count);
}
extractMax() {
if (this.count <= 0) return;
const ret = this.data[1];
this.swap(this.data, 1, this.count);
this.count--;
this.shiftDown(1);
return ret;
}
shiftUp(k) {
while (k >= 1 && this.data[k] > this.data[Math.floor(k / 2)]) {
this.swap(this.data, k, Math.floor(k / 2));
k = Math.floor(k / 2);
}
}
shiftDown(k) {
//判断有左孩子
while (2 * k <= this.count) {
let j = 2 * k;
if (j + 1 <= this.count && this.data[j] < this.data[j + 1]) {
//判断是否有右孩子并且值大
j += 1;
}
if (this.data[k] >= this.data[j]) break;
this.swap(this.data, k, j);
k = j;
}
}
swap(arr, index1, index2) {
[arr[index1], arr[index2]] = [arr[index2], arr[index1]];
}
}
function heapSort(arr) {
// const maxHeap = new MaxHeap(arr.length + 1);
// for (let i = 0; i < arr.length; i++) {
// maxHeap.insert(arr[i]);
// }
// for (let i = arr.length; i > 0; i--) {
// const v = maxHeap.extractMax();
// arr[i - 1] = v;
// }
// return arr;
const maxHeap = new MaxHeap(arr, arr.length);
for (let i = arr.length; i > 0; i--) {
const v = maxHeap.extractMax();
arr[i - 1] = v;
}
return arr;
}