关于堆的一切

打印 上一主题 下一主题

主题 902|帖子 902|积分 2706

前置知识

首先给出堆的定义:
堆是一颗树,满足堆的性质,即:
对于一个节点,它的权值大于(或小于)它的各个儿子的权值
有这个性质,显然
堆的根节点权值是整个堆中最大或最小的
由此可分为小根堆大根堆
二叉堆

最常见的堆就是二叉堆
二叉堆是一颗满足堆的性质完全二叉树
显然,二叉堆的子树也是二叉堆
接下来,我们以小根堆为例:
当一个节点权值小于其父亲时,我们尝试不断将这个节点与父亲交换,直到其满足堆的性质
这就是向上调整
同理,
当一个节点权值大于其父亲时,我们尝试不断将这个节点与其两个儿子中权值较小的一个交换,直到其满足堆的性质
这就是向下调整
为什么这里要与权值较小的一个交换呢?
因为我们要使交换后满足堆的性质
所以新的父节点权值应小于它的两个儿子
由于堆的高度为 \(\log{n}\)
所以以上两个操作复杂度显然为 \(\mathcal {O}(\log{n})\)
那么有了这两个操作我们就可以完成:
插入(新建节点然后向上调整)
查询最大(最小)值(根节点权值)
删除最大(最小)值(与末尾节点交换,再向下调整)
删除任意节点(与末尾交换,再向上或向下调整,见代码)
修改任意节点权值(向上或向下调整)
Luogu (模板)堆
[code]#includeusing namespace std;static constexpr int AwA = 1e6 + 10;inline static int Read() {    int res = 0;    bool flag = false;    int c = getchar();    while ((c < '0' || c > '9') && ~c) {        flag |= c == '-';        c = getchar();    }    while (c >= '0' && c > 1) {        int fa = u >> 1;        if (val[fa]
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表