11package com .bruis .algorithminjava .algorithm .sort ;
22
3+ import java .util .Random ;
4+
35/**
6+ *
7+ * 原地堆排序! 不需要额外的空间
8+ *
9+ * 这里构造出来的是一个最小堆!!!! 即数组的值依次递增
10+ *
411 * @author LuoHaiYang
512 */
613public 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}
0 commit comments