C++基础-堆排序

堆排序的个人理解

首先呢,希望学习堆排序的各位千万不要以为这个算法有多么的难,可以理解为“构造树”。


堆排序的过程就是构造树的过程。

这里先指明三个公式:
假设当前节点下标为i,则

  • 父节点的下标(i - 1) / 2
  • 左右叶子节点的下标分别是2 * i +1、2 * i + 2

排序的过程:
假设待排序数组为int a[10];
1. 遍历所有非叶子的节点,建立大根堆/小根堆的完全二叉树
2. 将树的根节点(a[0])与最后的子节点(a[9])交换位置
3. 把前面的9个元素重新建立树
4. 将树的根节点(a[0])与最后的子节点(a[8])交换位置
5. 把前面的8个元素重新建立树
6. …
7. 直到交换完毕

这么说不知道多少人能理解………..本人不太会画图,提供一篇文章,我觉得里面的图很容易理解

http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html

下面是代码实现,注释已经很清楚了

    /// 堆排序-整理堆
    void BuildHeap(int a[], int index, int size)
    {
        // 初始化待比较的值
        int value = a[index];
        // 判断叶子是否存在
        while (2 * index + 1 < size)
        {
            // 取出左叶子节点的下标
            int i = 2 * index + 1;
            // 比较左右两个叶子的大小(没越界的情况下)
            if (i + 1 < size && a[i] < a[i + 1])
            {
                i++;
            }
            // 待比较的父节点比叶子大则跳出
            if (value > a[i])
            {
                break;
            }
            // 父和叶子交换位置
            swap(a[index], a[i]);
            // 重排叶子
            index = i;
        }
    }
    /// 堆排序
    void HeapSort(int a[], int size)
    {
        // 建立大根堆
        // 最后的非叶子节点的下标为size/2
        for (int i = size / 2; i >= 0; i--)
        {
            // 构建树
            BuildHeap(a, i, size);
        }
        // 头尾交换,最值放到最后面的有序区,然后对其它无序区重构树
        for (int i = size - 1; i >= 0; i--)
        {
            // 头尾交换
            swap(a[0], a[i]);
            // 重新构建i - 1的元素树
            BuildHeap(a, 0, i - 1);
        }
    }

    void main()
    {
        int a[] = {10,9,8,7,6,5,4,3,2,1};
        HeapSort(a, sizeof(a) / sizeof(a[0]));
    }

markdown编辑器连颜色都不能变啊。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值