难度系数最高之堆排序简介

描述

今天来看一个比较复杂的排序,堆排序,先搞清楚原理,再写代码。

堆排序使用数据结构中的堆来完成,那么问题来了,什么是堆?

有两种,大顶堆和小顶堆,所谓大顶堆,就是任意一个双亲节点都比孩子节点大,比如图上这样的,小顶堆则反过来。

交换机

所以对于大顶堆来说,根节点一定是最大的。

比如有这样一个数组,先把它画成一颗二叉树的形式,接下来就是构建大顶堆,这个部分也是整个堆排序中最耗时的部分。

交换机

从0这个节点开始,因为节点0是最后一个有孩子的节点。

0比2小,交换一下位置。

交换机

再轮到4,8和9比较,显然是9大,把9和4交换一下位置。

交换机

最后轮到3,9比2大,9和3需要交换一下位置。

交换机

注意,因为这个节点发生了变化,所以3 8 4不再满足条件,还得继续调整。8比4大,8和3交换一下位置。

交换机

这个过程就是构建大顶堆。

于是,我们得到了最大的数字9,把它和最后一个数字做交换,然后断开,意思就是后面的操作跟9没有关系了。

交换机

接下来就是调整大顶堆,不需要再像刚才那样构建,因为这颗二叉树也只有根节点被修改了。

0和8交换,4和0交换,又得到了第二大的数字8。

交换机

不断的重复,最后就是一个有序的序列。

写代码之前,还得明确一个问题,虽然我们一直在操作二叉树,但是写代码的时候并不需要真的去创建一颗二叉树,我们只是在操作数组的下标,比如下标为n的节点作为根几点,那么他的左孩子就是 2n+1,右孩子就是2n+2。

 

#include 


void adjust_heap_sort(int *a, int root, int last)
{
    int child;


    while (1)
    {
        child = 2 * root + 1;
        if (child > last)
            break;


        if (child + 1 <= last && a[child] < a[child + 1])
        {
            child++;
        }


        if (a[child] > a[root])
        {
            int num = a[root];
            a[root] = a[child];
            a[child] = num;
        }


        root = child;
    }
}


void heap_sort(int *a, int size)
{
    //构建大顶堆
    for (int i = size / 2 - 1; i >= 0; i--)
    {
        adjust_heap_sort(a, i, size - 1);
    }


    //调整大顶堆
    for (int i = size - 1; i > 0; i--)
    {
        int num = a[0];
        a[0] = a[i];
        a[i] = num;


        adjust_heap_sort(a, 0, i - 1);
    }
}


int main()
{
    int array[] = {3, 4, 0, 8, 9, 2};


    heap_sort(array, 6);


    for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++)
    {
        printf("%d ", array[i]);
    }
    printf("
");


    return 0;
}
代码确实不太容易理解,不过在这些排序算法中,越是不容易理解的,效率也就越高,还是用它和冒泡做个对比,10000个数据,差距还是很大的。
root@Turbo:test# time ./heap_sort 


real  0m0.005s
user  0m0.004s
sys  0m0.000s
root@Turbo:test# time ./bubble_sort 


real  0m0.606s
user  0m0.554s
sys  0m0.000s
root@Turbo:test#
 

 




审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分