第一步: 把无序数组构建成二叉堆(最大堆或最小堆)
第二步:循环删除堆顶元素,并将该元素移到集合尾部,调整堆产生新的堆顶
时间复杂度:O(nlongn) 空间复杂度:O(1)
function heapSort(arr) {
// 把无序数组构建成最大堆
for (let i = (arr.length - 2) / 2; i >= 0; i--) {
downAdjust(arr, i, arr.length);
}
// 循环删除堆顶元素,移到末尾,调整产生新的堆顶
for (let i = arr.length - 1; i > 0; i--) {
[arr[i], arr[0]] = [arr[0], arr[i]];
downAdjust(arr, 0, i);
}
}
/**
*
* @param {待调整的堆} arr
* @param {要下沉的父节点} parentIndex
* @param {堆的有效大小} length
*/
function downAdjust(arr, parentIndex, length) {
// temp保存父节点值,用户最后的赋值
let temp = arr[parentIndex];
let childIndex = 2 * parentIndex + 1;
while (childIndex < length) {
// 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子
if (childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex]) {
childIndex++;
}
// 如果父节点大于任何一个孩子的值,则直接跳出
if (temp >= arr[childIndex]) {
break;
}
// 无须真正交换,单向赋值即可
arr[parentIndex] = arr[childIndex];
parentIndex = childIndex;
childIndex = 2 * childIndex + 1;
}
arr[parentIndex] = temp;
}