堆排序

排序思路分析

以升序为例,堆排序分为两个阶段:
1. 构建初始大顶堆(堆中每个节点都比左右child大);
2. 对大顶堆,每次都将堆顶元素与最后一个leaf交换,再对剩下的元素构建大顶堆,如此循环n次。

解释

1. 为什么升序/降序构建的是大顶堆/小顶堆?

因为第2步中,每次都是将堆顶元素后置,故数组排序是从后往前完成的,故与升降序表意相反

2. HeapSort第二个参数n是什么?

类似QuickSort,表示数组末尾元素的下标,即arr[n]是没有越界的

void swap(int &a, int &b) {
    int tmp = a;
    a = b;
    b = tmp;
}

void BuildHeap(int arr[], int start, int end) {
    int parent = start, lchild = parent * 2 + 1;
    int maxchild = lchild;                    // 标记最大的child位置
    while (lchild <= end) {                   // 注意!检查的是lchild而非maxchild
        maxchild = lchild;
        if (lchild + 1 <= end && arr[lchild + 1] > arr[lchild]) {
            maxchild = lchild + 1;            // 需要先判断是否有rchild,即其下标是否越界
        }
        if (arr[parent] >= arr[maxchild]) {   // 更常发生的分支
            break;
        } else {
            swap(arr[parent], arr[maxchild]); // 将maxchild元素置于parent位置
            parent = maxchild;                // 触发下一层child的大顶调整
            lchild = 2 * maxchild + 1;
        }
    }
}

void HeapSort(int arr[], int n) {           // 注意第二个参数为数组len - 1
    for (int i = (n - 1)/2; i >= 0; --i)    // 取到最后一个元素的parent,循环至root
        BuildHeap(arr, i, n);
    for (int i = 0; i < n; ++i) {           // 循环n次,即取n次未排序数组的最大值
        swap(arr[0], arr[n - i]);           // 后置大顶堆堆顶元素
        BuildHeap(arr, 0, n - i - 1);       // 重新构建大顶堆
    }
}

参考:http://blog.csdn.net/u013412497/article/details/52205785
*参考链接有错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值