# 解题思路 or 实现原理
堆排序(Heap sort
)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构, 并同时满足堆积的性质: 即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆: 每个节点的值都大于或等于其子节点的值, 在堆排序算法中用于升序排列;
小顶堆: 每个节点的值都小于或等于其子节点的值, 在堆排序算法中用于降序排列;
堆排序的平均时间复杂度为 Ο(nlogn)
。
# 算法步骤
创建一个堆 H[0……n-1];
把堆首(最大值)和堆尾互换;
把堆的尺寸缩小 1, 并调用 shift_down(0), 目的是把新的数组顶端数据调整到相应位置;
重复步骤 2, 直到堆的尺寸为 1。
# 实现代码
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors: Rainy
* @LastEditTime: 2019-11-24 20:50:03
*/
import { NumberArrayMap } from 'types';
export function heapSort(arr: NumberArrayMap): NumberArrayMap {
let len = arr.length;
if (len < 2) {
return arr;
}
buildMaxHeap(arr, len);
for (let i = arr.length - 1; i > 0; i--) {
swap(arr, 0, i);
len--;
heapify(arr, 0, len);
}
return arr;
}
function buildMaxHeap(arr: NumberArrayMap, len: number) {
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapify(arr, i, len);
}
}
function heapify(arr: NumberArrayMap, i: number, len: number) {
let left = 2 * i + 1;
let right = 2 * i + 2;
let largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
swap(arr, i, largest);
heapify(arr, largest, len);
}
}
function swap(arr: NumberArrayMap, i: number, j: number) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52