堆排序

算法思想:

借助最大堆的性质,堆的根节点是最大的节点,每次迭代将根节点从堆中摘除,用最末一个叶子节点替代原先的根节点,此时新生成的树不具有堆的性质,所以要对树的结构进行调整,让新树的根下降到较低的层次(最大堆的根节点不小于它的子节点),以此来重新构造一个最大堆。

 

算法步骤:

1、首先建立最大堆

2、排序思想是每次迭代都把根元素与最后一个元素交换,同时剔除根元素(heapSize - 1),再对交换上来的根进行调整,保持堆的性质。

 

 1 // 最大堆调整
 2 // i为待调整的根节点
 3 void maxHeapify(int *A, int i, int size) {
 4     // 根编号为0的左右孩子下标
 5     int l = 2 * i + 1;
 6     int r = 2 * i + 2;
 7     // 首先默认根节点为最大
 8     int largest = i;
 9     if (l < size && A[l] > A[i]) {
10         largest = l;
11     }
12     if (r < size && A[r] > A[largest]) {
13         largest = r;
14     }
15     if (largest != i) {
16         mySwap(A[largest], A[i]);
17         // 递归调整根为largest的子树
18         maxHeapify(A, largest, size);
19     }
20 }
21 
22 // 建最大堆
23 void buildMaxHeap(int *A, int size) {
24     // size/2至size-1为叶子节点
25     // 对非叶子节点进行调整
26     for (int i = (size - 1) / 2; i >= 0; i--) {
27         maxHeapify(A, i, size);
28     }
29 }
30 
31 void heapSort(int *A, int size) {
32     buildMaxHeap(A, size);
33     for (int i = size - 1; i >= 1; i--) {
34         // 将根元素交换到后面
35         mySwap(A[0], A[i]);
36         size -= 1;
37         // 交换后堆的性质可能没有保持,对新的根节点进行调整
38         maxHeapify(A, 0, size);
39     }
40 }

 算法分析:

buildMaxHeap()建堆的复杂度算法导论P88上的推算为O(n),即线性时间。堆调整maxHeapify()的复杂度为O(logn),所以heapSort()的复杂度为O(n + n*logn)=O(logn)。

 

posted @ 2013-10-09 17:21  StrikeW  阅读(229)  评论(0编辑  收藏  举报