Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fab524c

Browse files
[A] 添加堆排序
1 parent df8dc90 commit fab524c

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

‎src/main/java/com/bruis/algorithminjava/algorithm/sort/HeapSort.java‎

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
package com.bruis.algorithminjava.algorithm.sort;
22

3+
import java.util.Random;
4+
35
/**
6+
*
7+
* 原地堆排序! 不需要额外的空间
8+
*
9+
* 这里构造出来的是一个最小堆!!!! 即数组的值依次递增
10+
*
411
* @author LuoHaiYang
512
*/
613
public class HeapSort {
@@ -11,13 +18,22 @@ public static void sort(int[] arr) {
1118
// 注意,此时我们的堆是从0开始索引的
1219
// 从(最后一个元素的索引-1)/2开始
1320
// 最后一个元素的索引 = n-1
21+
// 其实这里 i = (n-1) 也行
1422
for (int i = (n - 1 - 1) / 2; i >= 0; i--) {
15-
shiftDown(arr, n, i);
23+
siftDown2(arr, n, i);
24+
}
25+
26+
// [a.....v,k]
27+
// [.......]k
28+
// [.....] ba
29+
for (int i = n-1; i > 0; i--) {
30+
swap(arr, 0, i);
31+
siftDown2(arr, i, 0);
1632
}
1733
}
1834

1935
// 下浮
20-
public static void shiftDown(int[] arr, int n, int k) {
36+
public static void siftDown(int[] arr, int n, int k) {
2137

2238
while (2 * k + 1 < n) {
2339
int j = 2 * k + 1;
@@ -32,9 +48,59 @@ public static void shiftDown(int[] arr, int n, int k) {
3248
}
3349
}
3450

51+
/**
52+
* 优化下沉过程, 不适用swap交换,通过赋值来代替。
53+
*
54+
* @param arr
55+
* @param n
56+
* @param k
57+
*/
58+
private static void siftDown2(int[] arr, int n, int k) {
59+
60+
int e = arr[k];
61+
62+
while (2 * k + 1 < n) {
63+
int j = 2 * k + 1;
64+
if (j + 1 < n && arr[j + 1] > arr[j]) {
65+
j++;
66+
}
67+
68+
if (e >= arr[j]) {
69+
break;
70+
}
71+
// 此时说明arr[j] > arr[k]; 所以让大值上浮;
72+
arr[k] = arr[j];
73+
k = j;
74+
}
75+
// 就是这一个替换,让此堆变成了最小堆;
76+
// 这是因为while循环结束后,最小值以及替换到了arr[k]了,所以
77+
arr[k] = e;
78+
}
79+
3580
public static void swap(int[] arr, int i, int j) {
3681
int tmp = arr[i];
3782
arr[i] = arr[j];
3883
arr[j] = tmp;
3984
}
85+
86+
public static void main(String[] args) {
87+
/*
88+
int n = 100;
89+
int[] test = new int[n];
90+
Random random = new Random();
91+
for (int i = 0; i < n; i++) {
92+
test[i] = random.nextInt(1000);
93+
}
94+
*/
95+
int n = 10;
96+
int[] test = {10, 41, 30, 28, 16, 22, 13, 19, 17, 15};
97+
98+
sort(test);
99+
100+
for (int i = 1; i < n; i++) {
101+
if (test[i-1] > test[i]) {
102+
throw new IllegalArgumentException("Error!");
103+
}
104+
}
105+
}
40106
}

‎src/main/java/com/bruis/algorithminjava/datastructures/heap/MaxHeap.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public MaxHeap(int[] data) {
4646
size = n;
4747

4848
// 这里需要注意,size / 2 得到的索引是二叉堆中最后一个非叶子节点。
49+
// 注意!!! 这里size / 2 是因为 data 从1开始的,所以最后一个非叶子节点为:size / 2
50+
// 如果是从0开始,则:size - 1
4951
for (int i = size / 2; i > 0; i++) {
5052
siftDown(i);
5153
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /