C++数据结构9:堆

1、概念

堆是一种能高效找最值的数据结构,适合频繁的插入、取值操作;而堆排序就是利用它来排序的过程。可分为大根堆和小根堆。

大根堆:每个节点的值大于其左右节点的值;小根堆:每个节点的值小于其左右节点的值。

2、实战例子

给定一个数组,输出数组的前m个最小值。利用堆结构。(快排、归并也可以实现)

// 向下调整函数:将第 x 个结点向下调整,恢复小根堆性质
void hp(int x)
{
    int t = x;  // t 保存当前最小值的位置(初始为自身)
    // 如果左子结点存在,且比当前值更小,则更新 t
    if(2 * x <= s && q[t] > q[2 * x]) t = 2 * x; 
    // 如果右子结点存在,且比当前最小值更小,则更新 t(这里是和最新t比较)
    if(2 * x + 1 <= s && q[2 * x + 1] < q[t])  t = 2 * x + 1;
    // 如果 t 被更新了,说明子节点中有更小的值,需要交换并递归调整
    if(x != t)
    {
        swap(q[x], q[t]);  // 交换当前节点与更小的子节点
        hp(t);             // 继续递归调整被换下去的子节点
    }
}
int main()
{
    int n, m;
    cin >> n >> m;  // 输入 n 个元素和 m 次弹出操作
    s = n;          // 初始堆的大小为 n
    // 读入堆的元素,下标从 1 开始
    for (int i = 1; i <= n; i++)  cin >> q[i];
    // 从最后一个非叶子节点开始向下调整,建堆
    for (int i = n / 2; i; i--) hp(i);
    // 执行 m 次“弹出最小值”的操作
    while (m--)
    {
        cout << q[1] << ' ';   // 输出堆顶(最小值)
        q[1] = q[s--];         // 用最后一个元素替换堆顶,并减小堆的大小
        hp(1);                 // 向下调整堆顶
    }
    return 0;
}

难点分析:

1、为什么要n/2?确保从堆的底部开始比较;

2、q[1]=q[s --]作用?顶部元素输出之后就没用了,换个元素; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值