堆排序之“堆排序HEAPSORT”

本文转自: http://blog.csdn.net/michealtx/article/details/7171807

 

(1)先用BuildMaxHeap()建立最大堆

(2)交换a[1]和a[heapSize],把最大的换到最后

(3)堆大小heapSize减1

(4)因为将最后一个元素换到堆顶可能会破坏堆的性质,所以调用MaxHeapIfy()将新的heapSize大小的堆调整最大堆

(5)将(2)~(4)重复heapSize-1次,这里的heapSize是最初的那个heapSize。因为一共有heapSize个元素,要换heapSize-1次,才能将大的都换到后面来,实现从小到             大排序。


 

[cpp]   view plain copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <time.h>  
  4.   
  5. #define BUFFER_SIZE 10  
  6.   
  7. void MaxHeapIfy(int *a,int i,int heapSize)  
  8. {  //保持堆的性质,详情可见《算法导论(第二版)》第六章6.2,此为建堆的辅助函数
  9.     int left=i;  
  10.     int right=i;  
  11.     int tmp;  
  12.     int largest=i;  
  13.       
  14.     while(i<=heapSize)  
  15.     {  
  16.         left=i<<1;//左子索引   
  17.         right=(i<<1)+1;//(移位运算比算术运算优先级低!)右子索引   
  18.         largest=i;  
  19.           
  20.         if(left<=heapSize&&a[i]<a[left])  
  21.         {  
  22.             largest=left;  
  23.         }  
  24.         if(right<=heapSize&&a[largest]<a[right])  
  25.         {  
  26.             largest=right;  
  27.         }  
  28.           
  29.         if(i!=largest)//不加这个判断可能会产生死循环,一个劲的在i这打转   
  30.         {  
  31.             tmp=a[i];  
  32.             a[i]=a[largest];  
  33.             a[largest]=tmp;  
  34.             i=largest;//其实消除递归就要看每次递归变化的那个量   
  35.         }  
  36.         else  
  37.         {  
  38.             break;  
  39.         }  
  40.     }  
  41. }  
  42.   
  43.   
  44. void BuildMaxHeap(int *a,int heapSize)  
  45. {  //因为堆从BUFFER_SIZE/2 + 1 开始为叶子节点,本身只有一个元素,故本身为大顶堆。
  46.     int i=0;  
  47.     for(i=BUFFER_SIZE/2;i>0;i--)  
  48.     {  
  49.         MaxHeapIfy(a,i,heapSize);  
  50.     }  
  51. }  
  52.   
  53. void HeapSort(int *a,int heapSize)  
  54. {  
  55.     int i=0;  
  56.     int tmp=0;  
  57.     BuildMaxHeap(a,heapSize);  
  58.   
  59.     for(i=heapSize;i>1;i--)  
  60.     {  
  61.         tmp=a[1];  
  62.         a[1]=a[heapSize];  
  63.         a[heapSize]=tmp;  
  64.           
  65.         heapSize--;  
  66.         MaxHeapIfy(a,1,heapSize);  
  67.     }  
  68. }  
  69. void Output(int *a,int len)  
  70. {  
  71.     int i=1;  
  72.       
  73.     for(i=1;i<=len;i++)  
  74.     {  
  75.         printf("%d ",a[i]);  
  76.     }  
  77.     printf("\n");  
  78. }  
  79.   
  80. int main()  
  81. {  
  82.     int i=0;  
  83.     int a[BUFFER_SIZE+1];//第一个位置即a[0]不用,这样计算子节点的索引简单点。   
  84.     memset(a,0,sizeof(a));  
  85.       
  86.     srand((unsigned)time(NULL));  
  87.     for(i=1;i<=BUFFER_SIZE;i++)  
  88.     {  
  89.         a[i]=rand()%BUFFER_SIZE;  
  90.     }  
  91.     printf("随机生成数组:");   
  92.     Output(a,BUFFER_SIZE);  
  93.     HeapSort(a,BUFFER_SIZE);  
  94.     printf("排序后的数组:");  
  95.     Output(a,BUFFER_SIZE);  
  96.     system("pause");  
  97.     return 0;  
  98. }  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值