Skip to content

Commit 2897e13

Browse files
Merge pull request wangzheng0822#387 from hdkn235/master
feat(排序):添加堆排序算法(java实现)
2 parents 1556c4a + 3e89171 commit 2897e13

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

java/28_sorts/HeapSort.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* 堆排序
3+
*/
4+
public class HeapSort {
5+
6+
/**
7+
* 排序
8+
* <p>
9+
* 堆元素是从数组下标0开始
10+
*
11+
* @param arr
12+
*/
13+
public static void sort(int[] arr) {
14+
if (arr.length <= 1) {
15+
return;
16+
}
17+
18+
// 1、建堆
19+
buildHeap(arr);
20+
21+
// 2、排序
22+
int k = arr.length - 1;
23+
while (k > 0) {
24+
// 将堆顶元素(最大)与最后一个元素交换位置
25+
swap(arr, 0, k);
26+
// 将剩下元素重新堆化,堆顶元素变成最大元素
27+
heapify(arr, --k, 0);
28+
}
29+
}
30+
31+
/**
32+
* 建堆
33+
*
34+
* @param arr
35+
*/
36+
private static void buildHeap(int[] arr) {
37+
// (arr.length - 1) / 2 为最后一个叶子节点的父节点
38+
// 也就是最后一个非叶子节点,依次堆化直到根节点
39+
for (int i = (arr.length - 1) / 2; i >= 0; i--) {
40+
heapify(arr, arr.length - 1, i);
41+
}
42+
}
43+
44+
/**
45+
* 堆化
46+
*
47+
* @param arr 要堆化的数组
48+
* @param n 最后堆元素下标
49+
* @param i 要堆化的元素下标
50+
*/
51+
private static void heapify(int[] arr, int n, int i) {
52+
while (true) {
53+
// 最大值位置
54+
int maxPos = i;
55+
// 与左子节点(i * 2 + 1)比较,获取最大值位置
56+
if (i * 2 + 1 <= n && arr[i] < arr[i * 2 + 1]) {
57+
maxPos = i * 2 + 1;
58+
}
59+
// 最大值与右子节点(i * 2 + 2)比较,获取最大值位置
60+
if (i * 2 + 2 <= n && arr[maxPos] < arr[i * 2 + 2]) {
61+
maxPos = i * 2 + 2;
62+
}
63+
// 最大值是当前位置结束循环
64+
if (maxPos == i) {
65+
break;
66+
}
67+
// 与子节点交换位置
68+
swap(arr, i, maxPos);
69+
// 以交换后子节点位置接着往下查找
70+
i = maxPos;
71+
}
72+
}
73+
74+
}

0 commit comments

Comments
 (0)