信息竞赛进阶指南--二叉堆(模板)
啥是二叉堆
二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
插入节点
在数组的最末尾插入新节点。然后自下而上调整子节点与父节点(称作up-heap或bubble-up, percolate-up, sift-up, trickle up, heapify-up, cascade-up操作):比较当前节点与父节点,不满足堆性质则交换。从而使得当前子树满足二叉堆的性质。时间复杂度为 。
删除根节点
删除根节点用于堆排序。
对于最大堆,删除根节点就是删除最大值;对于最小堆,是删除最小值。然后,把堆存储的最后那个节点移到填在根节点处。再从上而下调整父节点与它的子节点:对于最大堆,父节点如果小于具有最大值的子节点,则交换二者。这一操作称作down-heap或bubble-down, percolate-down, sift-down, trickle down, heapify-down, cascade-down,extract-min/max等。直至当前节点与它的子节点满足堆性质为止。
构造二叉堆
一个直观办法是从单节点的二叉堆开始,每次插入一个节点。其时间复杂度为。
最优算法是从一个节点元素任意放置的二叉树开始,自底向上对每一个子树执行删除根节点时的Max-Heapify算法(这是对最大堆而言)使得当前子树成为一个二叉堆。具体而言,假设高度为h的子树均已完成二叉堆化,那么对于高度为h+1的子树,把其根节点沿着最大子节点的分枝做调整,最多需要h步完成二叉堆化。可以证明,这个算法的时间复杂度为O(n)。
合并两个二叉堆
最优方法是把两个二叉堆首尾相连放在一个数组中,然后构造新的二叉堆。时间复杂度为,其中n、k为两个堆的元素数目。
如果经常需要合并两个堆的操作,那么使用二项式堆更好,其时间复杂度为。
实现:
// 二叉堆
int heap[SIZE], n;
void up(int p) {while (p > 1) {if (heap[p] > heap[p/2]) {swap(heap[p], heap[p/2]);p/=2;}else break;}
}
void down(int p) {int s = p*2;while (s <= n) {if (s < n && heap[s] < heap[s+1]) s++;if (heap[s] > heap[p]) {swap(heap[s], heap[p]);p = s, s = p*2;}else break;}
}
void Insert(int val) {heap[++n] = val;up(n);
}
int GetTop() {return heap[1];
}
void Extract() {heap[1] = heap[n--];down(1);
}
void Remove(int k) {heap[k] = heap[n--];up(k), down(k);
}
信息竞赛进阶指南--二叉堆(模板)相关推荐
- 信息竞赛进阶指南--搜索相关(模板)
ACM常用模板合集 // 深度优先遍历框架 void dfs(int x) {v[x] = 1;for (int i = head[x]; i; i = next[i]) {int y = ver[i ...
- 『ACM--算法--KMP』信息竞赛进阶指南--KMP算法(模板)
简介: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的核心是利用匹 ...
- 信息竞赛进阶指南--单调栈(模板)
a[n + 1] = p = 0; for (int i = 1; i <= n + 1; i++) {if (a[i] > s[p]) {s[++p] = a[i], w[p] = 1; ...
- 『ACM-数据结构』信息竞赛进阶指南--线段树
我们主要是讲代码实现,不是讲基本原理! 什么是线段树? 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点 ...
- 『ACM-算法-Hash算法』信息竞赛进阶指南--字符串哈希
字符串hash主要应用在: 寻找长度为n的主串S中的匹配串T(长度为m)出现的位置或次数的问题属于字符串匹配问题. 类似的还有KMP,我也有讲解. 原理: 将字符串中的每一个字母都看做是一个数字(例: ...
- 『ACM-算法-数据结构』信息竞赛进阶指南--树状数组 (模板)
写在前面: 我们是主要是讲算法模板,即实现的代码,并不讲实现的原理 什么是树状数组? 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度 ...
- 信息竞赛进阶指南--单调队列模板
// 单调队列 int l = 1, r = 1; q[1] = 0; // save choice j=0 for(int i = 1; i <= n; i++) {while (l < ...
- 信息竞赛进阶指南--递归法求中缀表达式的值,O(n^2)(模板)
// 递归法求中缀表达式的值,O(n^2) int calc(int l, int r) {// 寻找未被任何括号包含的最后一个加减号for (int i = r, j = 0; i >= l; ...
- 信息竞赛进阶指南--中缀表达式转后缀表达式并求值(模板)
// 后缀表达式转中缀表达式,同时求值,O(n)// 数值栈 vector<int> nums; // 运算符栈 vector<char> ops;// 优先级 int gra ...
最新文章
- 利用JSP编写程序初步
- PHP 查看系统文件时间戳
- python数据类型可变和不可变_python可变数据类型vs不可变数据类型
- Linux连接mysql 出现Access denied for user ‘root‘@‘localhost‘(using password: YES)错误解决方案
- 大整数减法的c语言程序,求用C编个大数加减法运算程序
- 重磅:达摩院医疗AI团队CVPR'20论文解读 | 凌云时刻
- PASCAL VOC 2012数据集
- Android运行原理及运行机制知识汇总
- HackerRank [Algo] Matrix Rotation
- Matlab 数值计算迭代求根方法总结
- kuka机器人码垛编程网盘_KUKA机器人码垛程序怎么写(案例)
- 如何使用Xcode的Targets来管理开发和生产版本的构建
- 父级fixed_position:fixed相对父级元素定位而不是浏览器
- C# 获取电脑序列号和主板序列号
- C语言实现求最小公倍数。
- BW处理链的几个操作
- Gym - 102263 B - Road to Arabella
- 【通信仿真】基于matlab噪声调频干扰仿真【含Matlab源码 1951期】
- Visual Studio 2022 vcvarsXXX.bat文件所在的目录
- 设置GPS模块ublox 的波特率和数据输出格式
热门文章
- QTablewidget只显示横分割线,不显示竖分割线
- qt下设置按钮不接收键盘鼠标但能响应 clicked()信号
- Android开发之高德地图定位成功返回的定位信息
- centos6.6安装hadoop-2.5.0(四、hadoop HA安装)
- X210串口配置与stdio移植
- python xml.dom模块解析xml
- Bada学习- C++以及Flash应用开发流程之创建应用工程
- 类5-类的继承、虚函数、纯虚函数、虚析构函数
- 973分成功通过CCNA。。
- [消息]C++ Connections 在拉斯维加斯召开年会