堆排序

来源:互联网 发布:java邮箱注册验证 编辑:程序博客网 时间:2024/04/26 16:43
 需要掌握的知识:

 大根堆

 根节点的值始终大于孩子节点的值的树结构如下

      9
     / /
    8   6
   / / / /
  7  1 4  2
 /
3


然后每次用根节点与最后一个节点替换,并用剩下的节点构造大根堆

时间复杂度为O(n*logn)

  1. #include <iostream>
  2. using namespace std;
  3. int cnt = 0; //计算次数
  4. void Output(int array[], int n)
  5. {
  6.     printf("%d:/t/t ", cnt++);
  7.     for (int i=1; i<n; i++)
  8.     {
  9.         printf("%d ", array[i]);
  10.     }
  11.     printf("/n");
  12. }
  13. void swap(int &a, int &b)
  14. {
  15.   printf("%d <--> %d/n", a, b);
  16.   int temp;
  17.   temp = a;
  18.   a = b;
  19.   b = temp;
  20. }
  21. /*
  22.   root从最下层的根开始排序,树的节点序号从1开始,左节点=2*根节点
  23.   index为节点数
  24.   函数目的:建立大根堆(根节点始终大于孩子节点的树结构)
  25.  */
  26. void CreateHeap(int array[], int root, int index)
  27. {
  28.   int j;
  29.   int temp;
  30.   int finish;
  31.   
  32.   j = 2*root; //左孩子节点索引值
  33.   temp = array[root]; //保存根节点
  34.   finish = 0;
  35.   while(j<=index && finish == 0)
  36.     {
  37.       if(j < index) //如果有右孩子
  38.     if(array[j] < array[j+1]) //选出值大的节点
  39.       j++;
  40.       if(temp >= array[j]) //和父节点比较
  41.     finish = 1;
  42.       else //取出最大值的节点做父亲
  43.     {
  44.       array[j/2] = array[j];
  45.       j = 2*j; //递归左节点
  46.     }
  47.     }
  48.   array[j/2] = temp;
  49. }
  50. int main()
  51. {
  52.   int a[9] = {0,7,9,6,8,1,2,4,3};
  53.   for(int k=8; k>0; k--)
  54.     {
  55.       a[9-k] = k+1;
  56.     }
  57.   for(int i=(8/2); i>0; i--)
  58.     {
  59.       CreateHeap(a, i, 8);
  60.       Output(a,9);
  61.     }
  62.   for(int j=8; j>1; j--)
  63.     {
  64.       swap(a[j], a[1]);
  65.       CreateHeap(a, 1, j-1);;
  66.       Output(a,9);
  67.     }
  68.   return 0;
  69. }
注意索引值从1开始,才有父节点索引=子节点索引值/2

原创粉丝点击