数据结构与算法(21): 排序- 堆排序

  堆排序是指利用堆这种数据结构所涉及的一种排序算法。最大堆通常被用来进行”升序”排序,而最小堆通常被用来进行”降序”排序。
  最小堆进行降序的基本思想
  1. 初始化堆:将数据构造成最小堆。
  2. 交换数据:将a[0] (最小值)和a[n-1]进行交换,并重新调整最小堆。每次deleteMin都确定一个数的顺序。

  时间复杂度:O($N\log{N}$)。
  空间复杂度:O($1$)。
  堆排序是不稳定的。它在交换数据的时候,是比较父结点和子节点之间的数据,所以,即便是存在两个数值相等的兄弟节点,它们的相对顺序在排序也可能发生变化。

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
/**
* 堆排序:从大到小(最小堆)
*/
public class HeapSort extends Sort {
public static void sort(int[] a) {
for (int i = a.length / 2; i >= 0; i--) {
percolateDown(a, i, a.length);
}
for (int i = a.length - 1; i >= 0; i--) {
// deleteMin 放到数组最后
swap(a, 0, i);
percolateDown(a, 0, i);
System.out.println("--------第"+(a.length - i)+"趟---------");
print(a);
}
}
/**
* 用于buildHeap和deleteMin
*
* @param a
* @param index 开始下滤的索引
* @param n 堆的逻辑大小
*/
private static void percolateDown(int[] a, int index, int n) {
int child;
int tmp;
for (tmp = a[index]; leftChild(index) < n; index = child) {
child = leftChild(index);
if (child != n - 1 && a[child] > a[child + 1]) {
// 右儿子
child++;
}
if (tmp > a[child]) {
a[index] = a[child];
} else {
break;
}
}
a[index] = tmp;
}
private static int leftChild(int i) {
return 2 * i + 1;
}
}

感谢:http://www.cnblogs.com/skywang12345/p/3602162.html