程序员必须掌握的十种算法---堆排序算法

来源:互联网 发布:手机淘宝链接打不开 编辑:程序博客网 时间:2024/05/16 07:34

堆排序,就是利用完全二叉树的某些特性对数组进行排序。

#include<stdio.h>int h[101];//用来存放堆的数组int n;//用来存储堆中元素的个数,也就是堆的大小//交换函数,用来交换堆中两个元素的值void swap(int x,int y){    int t;    t=h[x];    h[x]=h[y];    h[y]=t;}//向下调整函数//传入一个需要向下调整的结点编号i,//这里传入1,是从堆的顶点开始向下调整void siftdown(int i){    int t,flag=0;//flag用来标记是否需要继续向下调整    //当i结点有儿子(其实是至少有左儿子),并且有需要继续调整的时候循环    while(i*2<=n&&flag==0)    {        //首先判断它和左儿子的关系,并用t记录值较大的结点编号        if(h[i]<h[i*2])            t=i*2;        else            t=i;        //如果有右儿子,再对右儿子进行讨论        if(i*2+1<=n)        {            //如果右儿子值更小,更新较大的结点编号            if(h[i]<h[i*2+1])                t=i*2+1;        }        //如果发现最大的结点编号不是自己,说明子节点中有比父节点更大的        if(t!=i)        {            swap(t,i);//交换他们            i=t;//更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整        }        else            flag=1;//说明当前结点比两个子节点都要大,不需要在进行调整了    }}//建立堆的函数void creat(){    int i;    //从最后一个非叶结点到第一个结点依次向上调整    for(i=n/2;i>=1;i--)    {        siftdown(i);    }}//堆排序void heapsort(){    while(n>1)    {        swap(1,n);        n--;        siftdown(1);    }}int main(){    int i,num;    //读入要排序的数字的个数    scanf("%d",&num);    for(i=1;i<=num;i++)        scanf("%d",&h[i]);    n=num;    //建堆    creat();    //堆排序    heapsort();    //输出    for(i=1;i<=num;i++)        printf("%d ",h[i]);    getchar();    getchar();    return 0;}

以上代码参考《啊哈!算法》这本书,如果想更仔细的了解这些内容,推荐大家去看这本书。

0 0
原创粉丝点击