大根堆、小根堆(数组模拟操作)
1.什么是大根堆、小根堆?
首先堆应该是一颗完全二叉树,大根堆就是二叉树的所有父节点的值都比左右孩子的值大,小根相反。下面是大根堆和小根堆的图:
如上,左图是一个大根堆,右图是一个小根堆。
2.树的数组存储
我们可以将树存储在一个数组中:
根结点存储在位置0,根的左孩子存储在位置1,右孩子存储在位置2。由此可以得出如下公式:
如果父节点的位置为i,那么他的左孩子和右孩子的位置分别为2*i+1和2*i+2。
如果一个结点的位置为i,那么他的父节点的位置为(i-1)/2;
3.大根堆小根堆的操作
由于大根堆和小根堆的操作基本相同,只是结点比较的方式不一样,一个取大,一个取小。我们在这里以大根堆为例。
3.1大根堆的插入操作
如上,我们在大根堆中插入一个元素45,首先先将元素插入在树的右下角(数组的末尾),然后将45与其父节点23比较,发现它比23大,将45与23交换,然后再将45与其新的父节点32比较,发现还比32大,再交换位置,再与54比较,发现比54小,位置不变,插入完成。
3.2大根堆的删除操作
首先大根堆只能删除根节点,另外,为了保证堆是一颗完全二叉树的特性,我们将树的右下角的元素赋值给根节点,然后将右下角节点删除(在数组中:将第一个元素删除,将最后一个元素赋值给第一个元素,将最后一个位置删除),然后调整二叉树。
如上图:我们要删除55,将右下角元素0赋值给55(也可以交换,然后不用管最后一个结点),这时根结点变为0,左后孩子分别为54和12,取左右孩子的最大值:54,54>0,将0和54交换位置,这时它的左右孩子变为44和23,取最大孩子44,44>0,交换位置,重复上述操作,直至0比它的左右孩子的值都大,或者没有左右孩子。
3.3代码实现
template<typename type>class MaxHeap
{public://插入操作void Insert(type e){//将新添加的结点插入到队尾_maxHeap.push_back(e);//得到自己和父节点的索引int selfIndex = _maxHeap.size() - 1;int fatherIndex = (selfIndex - 1) / 2;//将新插入的元素放入到合理的位置while (fatherIndex >= 0 && selfIndex != 0){if (_maxHeap[fatherIndex] >= e)break;_maxHeap[selfIndex] = _maxHeap[fatherIndex];selfIndex = fatherIndex;fatherIndex = (fatherIndex - 1) / 2;}_maxHeap[selfIndex] = e;}//删除操作void Delete(){//删除堆顶元素if (!_maxHeap.empty()){cout << "删除了堆顶元素:" << _maxHeap[0] << endl;//将末尾元素赋值给堆顶_maxHeap[0] = _maxHeap[_maxHeap.size() - 1];//将末尾元素删除_maxHeap.pop_back();}//从上到下对堆进行调整Adjust();}void Adjust(){if (_maxHeap.empty())return;//堆顶元素type topEle = _maxHeap[0];int fatherIndex = 0;int childIndex = fatherIndex * 2 + 1;while (childIndex < _maxHeap.size()){//如果右孩子也存在,指向左右孩子中较大的结点if (childIndex + 1 < _maxHeap.size() && _maxHeap[childIndex] < _maxHeap[childIndex + 1])childIndex++;if (_maxHeap[childIndex] <= topEle)break;_maxHeap[fatherIndex] = _maxHeap[childIndex];fatherIndex = childIndex;childIndex = childIndex * 2 + 1;}_maxHeap[fatherIndex] = topEle;}void Show(){for (auto ele : _maxHeap){cout << ele << ends;}cout << endl;}
private:vector<type> _maxHeap;
};
大根堆、小根堆(数组模拟操作)相关推荐
- 堆——神奇的优先队列 大根堆小根堆详解,附小根堆C++代码实现与STL相关
文章目录 前置知识 堆操作 小根堆插入 代码实现 小根堆删除 代码实现 测试代码 STL实现--priority_queue 1.使用 2.创建 3.成员函数 前置知识 堆是一个完全二叉树(最后一层可 ...
- 二叉堆 | 大根堆 小根堆
目录 何为二叉堆 二叉堆的调整 最大堆 最大堆的插入操作 最大堆的删除操作 最大堆的构建 最大堆code 最小堆 小根堆的插入操作 最小堆的删除操作 最小堆的构建 最小堆code 二叉堆的存储方式 何 ...
- 哈夫曼编码之大根堆小根堆揭西县
哈夫曼编码 根据数据出现的频率对数据进行编码,从而压缩原始数据. 例如对于一个文本文件,其中各种字符出现的次数如下: a : 10 b : 20 c : 40 d : 80 可以将每种字符转换成二进制 ...
- day36: 数据流中的中位数(大根堆小根堆)
问题描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. ...
- 二叉堆------小根堆
二叉堆是完全二叉树,每个结点中存有一个元素. 小根堆堆性质:父亲的权值不大于儿子的权值. 插入操作 插入操作是指向二叉堆中插入一个元素,要保证插入后也是一棵完全二叉树. 最简单的方法就是,最下一层最右 ...
- 小根堆创建,插入,删除,排序等操作图解
堆:是用数组实现的完全二叉树,没有使用指针,根据数组的下标进行构建堆 eg:parentIndex = i;-> leftIndex = 2i+1;rightIndex = 2i+2; 堆的分类 ...
- 堆(大根堆、小根堆)
完全二叉堆 堆又可称之为完全二叉堆.这是一个逻辑上基于完全二叉树.物理上一般基于线性数据结构(如数组.向量.链表等)的一种数据结构. 完全二叉树的存储结构 学习过完全二叉树的同学们都应该了解,完全二叉 ...
- 大根堆和小根堆的区别
大根堆和小根堆的区别 文章转自:https://blog.csdn.net/weixin_37197708/article/details/79546535 堆的概念 堆实际上是一棵完全二叉树,其任何 ...
- 大根堆的删除c语言,大根堆和小根堆的C语言实现
大根堆小根堆的实现:以PPT形式呈现大根堆构建的理论过程 1.首先涉及到一个堆的调整,这也是算法的核心部分.假设树中,节点i的子树已经为两个大根堆.这两个子树再加上i节点的话,可能是大根堆也可能不是, ...
最新文章
- 《JS权威指南学习总结--第八章 函数》
- Linux 常用命令全称,看看你 get 到了哪些?
- ASP数据库插马小议
- 第二阶段—个人工作总结03
- PHP与Redis结合令牌桶算法进行实现限流
- Google App Engine使用简介
- 晕了!这个配置值从哪来的?
- .NET Core 收徒,有缘者,可破瓶颈
- 构建可扩展的有状态服务
- LeetCode 长度最小的子数组
- 全国计算机等级考试汇编,2011年3月汇编全国计算机等级考试(南开100题三级网络技术上机试题汇编)...
- OpenShift 4 之 GitOps(7)用ArgoCD部署Pacman应用集群
- 若依如何去掉“正在加载系统资源,请耐心等待”
- 谁扰乱了中国的工资秩序?
- 曾经如日中天的VB编程,现已没落,而惨遭嫌弃的它,成了香饽饽
- 机器学习导论(五)-神经元网络
- 纯Css比较好看的中英文字体样式(持续整理版)
- js中this是什么?this的5种用法
- 基于单目视觉的平面目标定位和坐标测量 (下) - 相机姿态估计和目标测量
- KEIL、uVision、RealView、MDK、KEIL C51区别