0%

堆排序理解

堆排序的关键是构建大(小)顶堆,堆顶元素就是最大(小)的元素,然后堆顶元素和末尾元素交换位置,再次堆化除最后一个元素外的其它元素,循环次过程即可完成排序。

翻译成代码如下:

1
2
3
4
5
6
7
public void sort(int a) {
for(int i = a.length - 1; i > 0; i--) {
buildHeap(a, i);
// 堆顶元素和最后一个元素交换,除过最后一个元素外其它元素再次构建大顶堆
swap(a, 0, i);
}
}

堆化过程

1、从序列最后一个非叶子节点开始
2、堆化规则:替换节点为当前节点和叶子节点中值最大的节点
3、倒序依次处理其它非叶子节点
4、须保证叶子节点也满足堆化规则

前置知识

1、堆是完全二叉树
2、满二叉树使用数组存储最省空间
3、若节点在数组中的下标为 n,其左叶子节点在数组中的下标为 2 * n + 1,右子节点下标为 2 * n + 2,父节点下标为 (n - 2)/2

堆化过程图解

堆化过程

翻译成代码如下:

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
/**
* 构建大顶堆
*
* @param a 数组
* @param n 最后一个元素下标
*/
public static void buildHeap(int[] a, int n) {
// 从最后一个非叶子节点开始,倒序依次处理其它非叶子节点
for(int i = (n -1) / 2; i >=0; i--) {
heapify(a, n, i);
}
}

/**
* 堆化
*
* @param a 数组
* @param n 最后一个元素下标
* @param i 需要调整的父节点下标
*/
public static void heapify(int[] a,int n, int i) {
while (true) {
// 大顶堆规则:替换节点为当前节点和叶子节点中值最大的节点
int maxPos = i;

int l = 2 * i + 1;
if (a[l] > a[maxPos]) {
maxPos = l;
}

int r = 2 * i + 2;
if (a[r] > a[maxPos]) {
maxPos = r;
}

// 当前节点最大时退出
if (maxPos == i) {
return;
}

swap(a, maxPos, i);

// 保证叶子节点也满足堆化规则
i = maxPos;
}
}

public static void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
欣赏此文?求鼓励,求支持!
Title - Artist
0:00