堆排序(代码2)




 堆一个常见的应用:作为高效的优先队列.

 我们可以在一个线性时间内将一个无序数组构造成一个最大堆,并且在O(lgn)的时间内调整堆.堆排序的时间复杂度为:O(nlgn).
  1  1 #include <stdio.h>
  2   2 #include <stdlib.h>
  3   3 
  4   4 void build_heap(int data[], int);
  5   5 void adjust_heap(int data[], int);
  6   6 void heap_sort(int data[], int);
  7   7 int sub_max_heap(int data[], int, int);
  8   8 
  9   9 int main(int argc, char *argv[])
 10  10 {
 11  11     int i;
 12  12     int data[12] = {6, 10, 3, 5, 12, 8, 4, 23, 1, 2, 9, 7 };
 13  13 
 14  14     heap_sort(data, 12);
 15  15 
 16  16     for (i = 0; i < 12; ++i)
 17  17     {
 18  18         printf("%d ", data[i]);
 19  19     }
 20  20 
 21  21     printf("\n");
 22  22     return 0;
 23  23 }
 24  24 
 25  25 void heap_sort(int data[], int num)
 26  26 {
 27  27     int i = 1;
 28  28     build_heap(data, num);
 29  29 
 30  30     for (i = 1; i < num; ++i)
 31  31     {
 32  32         int temp;
 33  33         temp = data[0];
 34  34         data[0] = data[num - i];
 35  35         data[num - i] = temp;
 36  36 
 37  37         adjust_heap(data, num - i);    
 38  38     }
 39  39 
 40  40 }
 41  41 
 42  42 
 43  43 void build_heap(int data[], int num)
 44  44 {
 45  45     int 46 
 46  47     for (i = num / 2 - 1; i >= 0; --i)
 47  48     {
 48  49         k = sub_max_heap(data, num, i);
 49  50         if (k == i)
 50  51             continue;
 51  52 
 52  53         while (2 * k + 1 < num)
 53  54         {
 54  55             p = k;
 55  56             k = sub_max_heap(data, num, p);
 56  57             if (k == p)
 57  58                 break;
 58  59         }
 59  60     }
 60  61 
 61  62 }
 62  63 
 63  64 
 64  65 void adjust_heap(int data[], int num)
 65  66 {
 66  67     int temp;
 67  68     int k, p;
 68  69 
 69  70     k = 0;
 70  71     while(2 * k + 1 < num)
 71  72     {
 72  73         p = k;
 73  74         k = sub_max_heap(data, num, p);
 74  75         if (k == p)
 75  76             break;
 76  77     }
 77  78 
 78  79 
 79  80 }
 80  81 /*
 81  82 int sub_max_heap(int data[], int num, int i)
 82  83 {
 83  84     int k;
 84  85 
 85  86     if (2 * i + 2 <= num - 1 && data[2 * i + 1] > data[2 * i + 2])
 86  87         k = 2 * i + 1;
 87  88     else if (2 * i + 2 <= num - 1)
 88  89         k = 2 * i + 2;
 89  90     else
 90  91         k = 2 * i + 1;
 91  92 
 92  93     if (data[k] > data[i])
 93  94     {
 94  95         int temp;
 95  96         temp = data[k];
 96  97         data[k] = data[i];
 97  98         data[i] = temp;
 98  99     }
 99 100     
100 101     return k;
101 102 
102 103 }
103 104 */
104 105 /*返回一个最大值的标记.即结点i的值,结点i的左孩子值和结点i的右孩子值中的最大值的标记*/
105 106 int sub_max_heap(int data[], int num, int i)
106 107 {
107 108     int largest;
108 109     int l, r;
109 110 
110 111     l = 2 * i + 1;
111 112     r = 2 * i + 2;
112 113     
113 114     if (l <= num - 1 && data[l] > data[i])
114 115         largest = l;
115 116     else
116 117         largest = i;
117 118     
118 119     if (r <= num - 1 && data[r] > data[largest])
119 120         largest = r;
120 121     if (largest != i)
121 122     {
122 123         int temp;
123 124         temp = data[i];
124 125         data[i] = data[largest];
125 126         data[largest] = temp;
126 127     }
127 128 
128 129     return largest;
129 130 }

 

posted @ 2014-09-28 11:33  yyxayz  阅读(175)  评论(0编辑  收藏  举报