堆排序

堆排序是比较难以理解的算法,构造不同的堆(大顶堆/小顶堆)可以得到不同的排列顺序。如果我们需要将数组进行从小到大的顺序排列,就需要构造大顶堆。为了方便个人复习,在这里给出我自己调试通过的一段代码:

 1 #include <stdio.h>
 2 typedef int Item;
 3 // 构造大顶堆
 4 void heap_adjust(Item a[], int parent, int length)
 5 {
 6     Item temp  = a[parent];      // 保存当前父节点
 7     int  child = 2 * parent + 1; // 先获得左孩子(若下标从1开始,则左孩子为2*parent)
 8 
 9     while (child < length){
10         //如果有右孩子节点,并且右孩子节点的值大于左孩子节点,则选取右孩子节点
11         if (child+1 < length && a[child] < a[child+1]){// child+1<length防止数组越界
12             child++;
13         }
14         //如果父节点的值已经大于孩子节点的值,则直接结束循环
15         if (temp >= a[child]) break;
16         //把孩子节点的值赋给父节点
17         a[parent] = a[child];
18         //选取孩子节点的左孩子节点,继续向下筛选(必须保证每次调整后,底部的树也是大顶堆)
19         parent = child;
20         child  = 2 * parent + 1;
21     }
22     a[parent] = temp;//将根结点放到最终位置上
23 }
24 
25 void heap_sort(Item a[], int left, int right)
26 {
27     int i, length = right - left + 1;
28     Item t;
29     //循环建立初始堆(从下往上构造大顶堆),注意下标从0开始时i=n/2-1
30     for (i = length/2-1; i >= 0; i--){
31         heap_adjust(a, i, length);
32     }
33 
34     //进行n-1次循环,完成排序
35     for (i = length - 1; i > 0; i--){
36         t = a[0]; a[0] = a[i]; a[i] = t; //最后一个元素和第一个元素交换
37         heap_adjust(a, 0, i);//筛选R[0]节点,得到n-1个节点的堆
38     }
39 }
40 
41 
42 int main()
43 {
44     int a[] = {1,3,2,5,4,3,7,2,9,8};
45     heap_sort(a, 0, 9);
46     
47     return 0;
48 }

 

posted @ 2015-08-12 10:34  XiaoManon  阅读(204)  评论(0编辑  收藏  举报