堆排序

大根堆定义为,每一个父亲节点都大于等于左右两个孩子节点(小根堆同理)。并且,大根堆一定是一棵完全二叉树。思想为从最后一个家庭开始(最后一个有孩子的父亲节点),将这个家庭调整为大根堆,然后父亲节点前移,将下一个家庭调整为大根堆……以此类推,最后,根节点就是最大的元素,然后将根节点与最后一个叶子节点交换,砍掉最后一个叶子节点(意思就是下一轮的排序它不参与)。

#include <stdio.h>

void HeapSort(int a[],int n)
{
    int rear,t,pa,tag=0;//tag:标志变量 用处:检查大根堆是否完成 
    rear=n;
    while(rear>1)
    {
        while(1)//与检查tag变量是否有变化一起合作,调整成大根堆 
        {
            pa=rear/2;//最后一个父亲节点,rear奇偶情况都适用
            tag=0;
            while(pa>0)
            {
                if(a[pa]<a[pa*2])//左子女不用检查 直接比较 
                {
                    t=a[pa];
                    a[pa]=a[pa*2];
                    a[pa*2]=t;
                    tag=1;
                }
                if(2*pa+1<=rear&&a[pa]<a[pa*2+1])//右子女检查是否存在 再比较 
                {
                    t=a[pa];
                    a[pa]=a[pa*2+1];
                    a[pa*2+1]=t;
                    tag=1;
                }
                pa--;
            }
            if(!tag)//是否调整成大根堆的判断 
            break;
        }
        t=a[1];//交换"头""尾" "砍掉"! 
        a[1]=a[rear];
        a[rear]=t;
        rear--;
    }
}

int main(void)
{
    int a[11]={0,1,3,6,8,4,2,5,9,7,10};
    int i;
    HeapSort(a,10);
    for(i=10;i>0;i--)
    printf("%d\t",a[i]);
    return 0;
}

时间复杂度:o(nlogn) 不稳定

点赞