堆排序

来源:互联网 发布:上古卷轴5可爱妹子数据 编辑:程序博客网 时间:2024/06/16 21:27

堆排序就是利用堆进行排序的方法,基本思想是,将代排序列构造成一个大根堆,此时整个序列的最大值就是堆顶的根节点。将它与堆数组的末尾元素交换,此时末尾元素就是最大值,移除末尾元素,然后将剩余n-1个元素重新构造成一个大根堆,堆顶元素为次大元素,再次与末尾元素交换,再移除,如此反复进行,便得到一个有序序列

(大根堆为每一个父节点都大于两个子节点的堆)


上面思想的实现还要解决两个问题:


1.如何由一个无须序列构造成一个堆?

2.在输出堆顶元素后,如何调整剩余元素成为一个新的堆?


void Heapsort(int *arr,int len){    //构建大根堆,i = len/2这句话代表找到最后一个非叶子节点,从下往上进行调整    for(int i = len/2;i > 0;i--)        HeapAdjust(arr,i,len);    for(int i = len;i > 1;i--)    {        //把堆顶数据和最后一个数据交换swap(arr[1],arr[i]);        //每次把交换后的最大数据移除,然后在重新构建大根堆        HeapAdjust(arr,i,len-1);    }}void HeapAdjust(int *arr,int s,int m){    int tmp,j;    tmp = arr[s];    for(j = 2*s;j <= m;j*=2)    {if(j<m && arr[j] < arr[j+1])    j++;if(tmp >= arr[j])    break;arr[s] = arr[j];        s = j;    }    arr[s] = tmp;}
构建大根堆思路:从最后一个结点的父节点开始(i),进入HeapAdjust,比较其与其子节点中较大值的大小,如果比其较大值大,则不动,如果比较大值小,则交换其与较大值,然后heapsort中的i--,从下往上依次比较,当i=1时,交换后的堆未必为大根堆,所以继续进入HeapAdjust,从上往下再次调整,直到大根堆构建完成,这样我们就解决了第一个问题。

调整剩余元素构建一个新的堆:heapsort中第二的for循环中HeapAdjust(arr,1,i-1),每次去掉最后一个数据重新调整堆,第二个问题解决。

原创粉丝点击