数据结构 堆排序原理及其实现

来源:互联网 发布:win7如何建立网络连接 编辑:程序博客网 时间:2024/05/19 01:08

堆:堆是具有特殊性质的二叉树

每个结点都大于其左右儿子的的二叉树叫大顶堆

每个结点都小于其左右儿子的二叉树叫做小顶堆




堆排序图解:

 给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

    首先根据该数组元素构建一个完全二叉树,得到

 
 然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

20和16交换后导致16不满足堆的性质,因此需重新调整

这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

此时3位于堆顶不满堆的性质,则需调整继续调整





代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int q[10005];void HeapAdjust(int loc,int len)             {    int pos=loc;                             //最大值的位置(左儿子 右儿子 自己)    int left_child=2*loc;    int right_child=2*loc+1;    if(loc<=len/2)                           //叶子没有左右儿子 所以不用比较    {        if(left_child<=len&&q[left_child]>q[pos])             //小顶堆改小于号即可  下同            pos=left_child;        if(right_child<=len&&q[right_child]>q[pos])            pos=right_child;        if(pos!=loc)                        //最大值不在loc位置   交换后再比较        {            swap(q[pos],q[loc]);            HeapAdjust(pos,len);        }    }    return;}void heapsort(int len){    int i;    for(i=len/2;i>=1;i--)                 //初始化成为大顶堆        HeapAdjust(i,len);    for(i=len;i>=1;i--)                        {        swap(q[1],q[i]);                  //将最大值放置于i处        HeapAdjust(1,i-1);                //找前i-1个的最大值    }    return;}int main(){    int n,i;    scanf("%d",&n);                     //输入n个数    for( i=1; i<=n; i++)        scanf("%d",&q[i]);    heapsort(n);    for(i=1; i<=n; i++)        cout<<q[i];    cout<<endl;    return 0;}



0 0
原创粉丝点击