经典算法-堆排序
概念:
1.堆排序(Heapsort)是指利用堆积树(堆)这种数据所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中选取最大(或最小)数值或者关键字的记录变得简单
2.堆是完全二叉树,树中的每一个节点对应于原始数据的一个纪录,并且每个节点应该满足如下条件:
非叶节点的数据大于或者等于左右节点的数据(若是按照从大到小的顺序,则要求非叶结点小于或者等于其左右孩子节点的数据)
堆排序2个步骤:
步骤一:在对的构造阶段,我们将原始数据进行重新安排到一个满足上述所说的堆中;
步骤二: 对其进行下沉排序
复杂度:
下沉排序:N个元素的构造堆,需要少于2N次比较和少于N次交换。
堆排序: N个元素的构造堆,其复杂度小于为O(2NlgN+2N)以及少于一半次数的交换。
代码:
1 #include<stdio.h> 2 #define ARRAYLEN 10 3 void HeapAjust(int a[],int s,int n)//构成堆,s是节点位置,n是长度 4 { 5 int j,t; 6 while(2*s+1<n) 7 { 8 j=2*s+1; 9 if((j+1)<n) 10 { 11 if(a[j]<a[j+1])//如果左子数小于右子数,则比较右子数 12 j++; 13 } 14 if(a[s]<a[j])//比较序号为s和j的数据 15 { 16 t=a[s]; 17 a[s]=a[j]; 18 a[j]=t; 19 s=j;//堆破坏,需要重新调整 20 } 21 else//比较左右孩子均大,则堆未被破坏,不需要调整 22 break; 23 } 24 }
1 void HeapSort(int[] a,int n)//堆排序 2 { 3 int t,i; 4 int j; 5 for(i=n/2-1;i>0;i--)//将a[0,n-1]建成大根堆 6 HeadAdjust(a,i,n); 7 for(i=n-1;i>0;i--) 8 9 { 10 t=a[0]; 11 a[0]=a[i]; 12 a[i]=t;//实现取出根节点位置的数 13 HeapAdjust(a,0,i);将a[0]和a[i]进行新一轮调整 14 } 15 }
1 int main() 2 { 3 int i,a[ARRAYLEN]; 4 for(i=0;i<ARRAYLEN;i++) 5 a[i]=0; 6 if(!CreatData(a,ARRAYLEN,1,100)) 7 { 8 Printf("生成随机数失败!\n"); 9 getch(); 10 return 1; 11 } 12 printf("原数据:"); 13 for(i=0;i<ARRAYLEN;i++) 14 Printf("%d",a[i]); 15 printf("\n") 16 HeadSort(a,ARRAYLEN); 17 printf("排序后:"); 18 for(i=0;i<ARRAYLEN;i++) 19 Printf("%d",a[i]); 20 printf("\n") 21 getch(); 22 return 0; 23 }
图例展示: