排序算法(六):堆排序

排序思路:
采用维护大根堆的方法,取堆顶(最大值)到已排序数组,同时从堆中剔除堆顶,用堆末尾元素补充到堆顶,进行下一轮堆维护。

是一种完整二叉树的数据结构。可以将待排序数组转化为堆结构。
最后一个非叶子节点:a[len/2-1]
若对于一个非叶子节点a[i],左孩子节点是a[2*i+1],右孩子节点是a[2*i+2]。

大根堆是指堆满足每一个非叶子节点都大于其孩子节点。

a[i]>=[2*i+1] && a[i]>=[2*i+2] 

例子:

{22,35,16,9,5,20} 
  1. 进行堆维护
        22
    35     16
  9   5  20

最后的非叶子节点是a[2]=16
16和20交换;

        22
    35     20
  9   5  16

重新维护;
a[1]=35和a[2]=20节点符合要求;
22和35交换;

        35
    22     20
  9   5  16

重新维护;
满足大根堆要求,本次维护结束。
2. 拿出堆顶a[0]=35,与数组末尾a[5]=16进行交换。
3. 排除数组末尾(已排序好的数组),进入下一轮堆维护。
4. 待维护堆变成

        16
    22     20
  9   5  

后续步骤省略。。。(懒了)

起始堆的维护可以看作是找最大值的过程。思路类似于选择排序,只不过选择排序是选出待排序的最小值,放到数组起始。

c实现

void adjustHeap(int array[], int len){

    /*
     *              0
     *        1           2
     *     3     4     5     6
     *   7  8  9  10 11 12 13 14
     *   array[i]父节点
     *   array[2*i+1]左孩子节点;array[2*i+2]右孩子节点;
     */

    int tmp;
    for(int i=len/2-1; i>=0; i--){

        /*
         * 从后向前遍历所有非叶子节点
         * 若存在孩子节点大于父节点的情况,就进行交换
         * 保持大根堆模型
         */

        //非子叶节点至少含有左孩子节点
        if(array[i]<array[2*i+1]) {
            tmp = array[i];
            array[i] = array[2 * i + 1];
            array[2 * i + 1] = tmp;
            adjustHeap(array,len);
        }

        //非子叶节点可能不含有右孩子节点,需要考虑越界情况
        if(array[i]<array[2*i+2] && (2*i+2)<len) {
            tmp = array[i];
            array[i] = array[2 * i + 2];
            array[2 * i + 2] = tmp;
            adjustHeap(array,len);
        }
    }
}

void heapSort(int array[], int len){
    int max;
    int cur_len=len;
    for(; cur_len>1; cur_len--) {
        adjustHeap(array, cur_len);
        max = array[0];
        array[0] = array[cur_len - 1];
        array[cur_len - 1] = max;
    }
}

平均时间复杂度是O(nlogn) ,节点遍历+堆排序(递归)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值