算法学习——堆排序

堆排序

类似于选择排序,但是相比于选择排序,利用“堆”的性质,提供了一种从未排序部分找到最大元素的有效方法,所需要的比较次数少得多。


Tips:

  • 时间复杂度:O(nlogn),最坏情况下仍为O(nlogn),因为“堆”使得速度有保证。
  • 空间复杂度:O(1)
  • 是一种不稳定排序
  • 如果要升序排,那么就要构建最大堆,每次调整完就把堆顶元素与最后一个元素交换,然后最后一个元素不再参与排序,不断缩小无序元素区间;
  • “头往上取,判断往下走”:构建一个最大堆时,start元素从最后一个dad节点往前取;再从start元素,往下判断or交换;
// 为了升序排,调整为最大堆
void maxHeapify(vector<int> &A, int start, int end){
    int dad = start, son = dad*2 + 1;
    while(son <= end){
        // 得到左右孩子中更大的那个
        if(son+1 <= end && A[son+1] > A[son])
            ++son;

        if(A[dad] > A[son])
            break;
        else{
            swap(A[son], A[dad]);
            dad = son;        // 从被交换过去的元素开始,再次判断
            son = 2*dad + 1;  // 从dad元素,逐渐往下走,直到超过end
        }
    }
}

void heapSort(vector<int> &A){
    int len = A.size();

    // Edge case:
    if(len == 1) return;

    // 首先,构建一个最大堆。start元素从最后一个dad节点开始,逐步往上取
    for(int start = len/2-1; start >= 0; --start){
        maxHeapify(A, start, len-1);
    }

    // 已经得到了一个最大堆,开始不断地把堆顶元素放到最后,作为已经排完序的元素,不再参与排序
    for(int end = len-1; end >= 1; --end){
        swap(A[0], A[end]);
        maxHeapify(A, 0, end-1);    // 最后一个元素,不再参与排序
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值