大小根堆的介绍

堆的简介
Heap是一种数据结构具有以下的特点:

1)完全二叉树
2)heap中存储的值是偏序

小根堆: 父节点的值小于或等于子节点的值
大根堆: 父节点的值大于或等于子节点的值

堆的存储
一般都用数组来表示堆,i结点的父结点下标就为(i–1)/2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。
注意:这里下标从0开始比较方便,因为0开始的话2x也是0,其子结点也是0。
在这里插入图片描述堆的基本操作
1.down
当堆中某个结点的值变大,比如下面的根结点,则与其最小的子节点做替换,一直往下移动,直至满足堆的特点。
在这里插入图片描述
2.up
当堆中某个结点的值变小,比如下面的子结点,则与其最小的父节点做替换,一直往上移动,直至满足堆的特点。
在这里插入图片描述
堆的操作:删除小根堆堆的最小元素
堆中每次都删除第0个数据。为了便于重建堆,实际的操作是将最后一个数据的值赋给根结点,堆的元素个数-1,然后再从根结点开始进行一次从上向下down的调整。
在这里插入图片描述
堆的操作:小根堆插入元素
插入一个元素:新元素被加入到heap的末尾,然后up更新树以恢复堆的次序。

在这里插入图片描述
例题如下:
在这里插入图片描述

#include <iostream>
const int N = 100010;
int h[N];
int n, m, num;
using namespace std;

void down(int i)
{
    int  t = i;
    if (2 * i <= num && h[2 * i] < h[t])
    {
        t = 2 * i;
    }
    if (2 * i + 1<= num && h[2 * i + 1] < h[t])
    {
        t = 2 * i + 1;
    }
    if (i != t)
    {
        swap(h[i], h[t]);
        down(t);
    }
}

void up (int i)
{
    while(i/2 && h[i/2] > h[i])
    {
        swap(h[i/2], h[i]);
        i = i /2;
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    num = n;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &h[i]);
    }
    for(int i = n/2; i; i --) { //创建堆时,一定要从后往前down,这样才能将后面的值往前引进
        down(i);
    }
    while(m --)
    {
        printf("%d ", h[1]);
        h[1] = h[num];
        num --;
        down(1);
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值