堆排序

堆:符合以下两个条件之一的完全二叉树:

根节点的值 ≥ 子节点的值,这样的堆被称之为最大堆,或大顶堆;
根节点的值 ≤ 子节点的值,这样的堆被称之为最小堆,或小顶堆。

堆排序的基本思想:

  将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根结点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,就能得到一个升序序列。

步骤一:构造初始堆.将给定无序序列构造成一个大顶堆

1.假定给定无序序列结构如下:
在这里插入图片描述
2.从最后一个非叶子结点开始,从左至右,从下至上进行调整

第一个非叶子结点:
在这里插入图片描述
第二个非叶子结点:
在这里插入图片描述
3.这时,交换导致子根[4,5,6]结构混乱,进一步调整,在代码中体现为:parent = child child = 2*parent+1.调整结束后,就将一个无序序列构造成了一个大顶堆.
在这里插入图片描述

步骤二:将堆顶元素与末尾元素交换,使末尾元素最大.然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素.如此反复进行交换、重建、交换.

代码实现

void adjustHeapDown(int arr[], int index, int len){
    if(arr == NULL || index >= len){
        return;
    }
    int parent = index;
    int child = 2 * parent + 1;
    while (child < len){
        if(child + 1 < len && arr[child] < arr[child + 1]) {
            child++;
        }
        if(arr[child] > arr[parent]) {
            swap(arr[child], arr[parent]);
        } else {
            break;
        }
        parent = child;
        child = 2 * parent + 1;
    }
}
void sortHeap(int arr[], int len){
    //1.构建大顶堆
    for(int i = (len - 2)/2; i >= 0; i--){
        adjustHeapDown(arr, i, len);
    }
    //2.调整堆结构 + 交换堆顶元素与末尾元素
    for(int i = len - 1; i > 0; i--){
        swap(arr[0],arr[i]);
        adjustHeapDown(arr, 0, i);
    }
}

练习题目:求数组中的第K个最大元素

剑指offer40:最小的k个数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值