C++ 手写自建小顶堆

基本概念:

堆排序原理和过程强烈推荐看这个up主 请叫我AXin

堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左子节点和右子节点的值。

最大堆和最小堆是二叉堆的两种形式。

最大堆:根结点的键值是所有堆结点键值中最大者。

最小堆:根结点的键值是所有堆结点键值中最小者。

而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。

最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。

以最大(小)层结点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。

代码关键:

1.下标为i的元素,父节点下标为 (i-1)/2

2.下标为i的元素,两个子节点下标为 左孩子:i * 2 + 1 右孩子:i * 2 + 2

3.长度为n的堆数组,从(n-1-1)/2 开始进行堆排序(对应代码中heapify),也就是n/2 - 1

代码:

class Heap {
public:
    void heapify(vector<int>&arr, int idx, int n){ // 从idx开始调整堆
        int left = (idx << 1) + 1, right = (idx << 1) + 2; // 孩子节点下标
        int minIdx = idx;
        if(left < n && arr[left] < arr[minIdx]) minIdx = left; 
        if(right < n && arr[right] < arr[minIdx]) minIdx = right;
        if(minIdx != idx){ // 如果孩子节点的值比父节点小,那么久swap然后继续检查孙子节点
            swap(arr[minIdx], arr[idx]);
            heapify(arr, minIdx, n);
        }
    }

    void heap(vector<int>&arr, int n){ // 之所以要指定堆大小,是因为arr可能比我们想要的堆更大
        for(int i = (n >> 1) - 1; i >= 0; --i){ // 堆的大小为n,则从n/2 - 1 开始建堆
            heapify(arr, i, n);
        }
    }
};

做笔记使用。如果有更好的写法还请赐教!!!!溜了溜了~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想是优秀社畜

您的打赏是对我最大的鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值