数据结构之排序——堆排序

来源:互联网 发布:勇者之塔觉醒数据 编辑:程序博客网 时间:2024/05/16 00:44

view plaincopy to clipboardprint?
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3.   
  4. #define MAX_SIZE 20  
  5. typedef int ElemType;   
  6.   
  7. // 定义排序表  
  8. typedef struct HeapList  
  9. {  
  10.     ElemType *keys;  
  11.     int length;  
  12. }HeapList;  
  13.   
  14. // 初始化排序表  
  15. void InitHeapList(HeapList &L)  
  16. {  
  17.     L.keys = (ElemType*)malloc(MAX_SIZE * sizeof(ElemType));  
  18.     L.length = 6;  
  19.     int data[] = {38, 11, 9, 27, 96, 83};  
  20.     for(int i = 0; i < 6; ++i)  
  21.         L.keys[i + 1] = data[i];  
  22. }  
  23.   
  24. // 打印排序表  
  25. void PrintHeapList(HeapList &L)  
  26. {  
  27.     for(int i = 1; i <= L.length; ++i)  
  28.         printf("%5d", L.keys[i]);  
  29.     printf("/n");  
  30. }  
  31.   
  32. //初始化大堆  
  33. void CreateBigHeap(HeapList &L)  
  34. {  
  35.     int middle = L.length/2;  
  36.     for(int i = middle; i > 0; i--)  
  37.     {  
  38.         if(((2*i + 1) > L.length) && (2*i <= L.length))   
  39.         {  
  40.             // 当没有右字树的时候只判断根节点和左字树的大小进行调换  
  41.             if(L.keys[i] < L.keys[2*i])  
  42.             {  
  43.                 L.keys[0] = L.keys[i];  
  44.                 L.keys[i] = L.keys[2*i];  
  45.                 L.keys[2*i] = L.keys[0];  
  46.             }  
  47.         }  
  48.         if((2*i + 1) <= L.length)  
  49.         {  
  50.             // 左右子数都有  
  51.             // 先比较左右字树哪个最大  
  52.             int max = 2 * i;  
  53.             if(L.keys[2*i] < L.keys[2*i + 1])max++;  
  54.             if(L.keys[i] < L.keys[max])  
  55.             {  
  56.                 L.keys[0] = L.keys[i];  
  57.                 L.keys[i] = L.keys[max];  
  58.                 L.keys[max] = L.keys[0];  
  59.             }  
  60.         }  
  61.     }  
  62. }  
  63.   
  64. // 初始化大堆之后,每一次的对前N-1个进行再次大堆  
  65. void heapfy(HeapList &L, int end)  
  66. {  
  67.     //此时出去root节点,其余的还是都符合大堆的,可以从头结点和他的子节点对比较,一直比到没有没有孩子结点或者满足大堆的时候停止  
  68.     for(int i = 1; 2*i <= end; i *=2)  
  69.     {  
  70.         if(2*i + 1 <= end)  
  71.         {  
  72.             // 还是三者对比,然后把i更新到替换到得为之  
  73.             int max = 2*i;  
  74.             if(L.keys[2*i] < L.keys[2*i + 1])max++;  
  75.             // 右字树最大,那么把该字树根节点和他对换吧  
  76.             L.keys[0] = L.keys[i];  
  77.             L.keys[i] = L.keys[max];  
  78.             L.keys[max] = L.keys[0];  
  79.             // 切记,更新i的位置  
  80.             i = max;  
  81.             // 接下来跳出if,进入for的下一个循环,该此时继续把i的自树进行如上操作  
  82.         }  
  83.         if(2*i + 1 > end && 2*i <= end)  
  84.         {  
  85.             // 只有左子树啦  
  86.             if(L.keys[i] < L.keys[2*i])  
  87.             {  
  88.                 L.keys[0] = L.keys[i];  
  89.                 L.keys[i] = L.keys[2*i];  
  90.                 L.keys[2*i] = L.keys[0];  
  91.             }  
  92.         }  
  93.     }  
  94. }  
  95.   
  96. //  堆排序  
  97. void HeapSort(HeapList &L)  
  98. {  
  99.     // 初始化一次大堆  
  100.     CreateBigHeap(L);  
  101.     // 把第一个和最后一个调换一下  
  102.     L.keys[0] = L.keys[1];  
  103.     L.keys[1] = L.keys[L.length];  
  104.     L.keys[L.length] = L.keys[0];  
  105.     for(int i = L.length - 1; i > 0; --i)  
  106.     {  
  107.         heapfy(L, i);     
  108.         L.keys[0] = L.keys[1];  
  109.         L.keys[1] = L.keys[i];  
  110.         L.keys[i] = L.keys[0];  
  111.     }  
  112. }     
  113.   
  114.   
  115. void main()  
  116. {  
  117.     HeapList L;  
  118.     InitHeapList(L);  
  119.     PrintHeapList(L);  
  120.     HeapSort(L);  
  121.     PrintHeapList(L);  
  122. }  

原创粉丝点击