二叉堆的介绍

二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两种:最大堆和最小堆。
最大堆:父结点的键值总是大于或等于任何一个子节点的键值;最小堆:父结点的键值总是小于或等于任何一个子节点的键值。示意图如下:

二叉堆一般都通过"数组"来实现。数组实现的二叉堆,父节点和子节点的位置存在一定的关系。

  1. 索引为i的左孩子的索引是 (2*i+1);
  2. 索引为i的左孩子的索引是 (2*i+2);
  3. 索引为i的父结点的索引是 floor((i-1)/2);

二叉堆的添加

假设在最大堆[90,80,70,60,40,30,20,10,50]种添加85,需要执行的步骤如下:

如上图所示,当向最大堆中添加数据时:先将数据加入到最大堆的最后,然后尽可能把这个元素往上挪,直到挪不动为止!
将85添加到[90,80,70,60,40,30,20,10,50]中后,最大堆变成了[90,85,70,60,80,30,20,10,50,40]。

二叉堆的删除

假设从最大堆[90,85,70,60,80,30,20,10,50,40]中删除90,需要执行的步骤如下:

如上图所示,当从最大堆中删除数据时:先删除该数据,然后用最大堆中最后一个的元素插入这个空位;接着,把这个“空位”尽量往下挪,直到剩余的数据变成一个最大堆。
从[90,85,70,60,80,30,20,10,50,40]删除90之后,最大堆变成了[85,80,70,60,40,30,20,10,50]。
注意:考虑从最大堆[90,85,70,60,80,30,20,10,50,40]中删除60,执行的步骤不能单纯的用它的字节点来替换;而必须考虑到"替换后的树仍然要是最大堆"!

二叉堆的实现

#pragma once
#include <iomanip>
#include <iostream>using namespace std;template<class T>
struct MaxHeap {MaxHeap();MaxHeap(int _mCapacity);~MaxHeap();void insert(T &data);                  //增加元素void remove(T &data);                 //删除元素void print();                         //打印堆
private:void filterUp(int start);               //最大堆的向上调整,添加堆元素时使用void filterDown(int start, int end);  //最大堆的向下调整,删除堆元素时调用int getIndex(T &data);                    //获取元素索引private:int mCapacity;  //总的容量int mSize;        //当前大小T * mHeap;        //数据
};template<class T>
MaxHeap<T>::MaxHeap()
{new (this)MaxHeap(30);  //使用new (this)重用构造函数
}template<class T>
MaxHeap<T>::MaxHeap(int _mCapacity) : mCapacity(_mCapacity), mSize(0)
{mHeap = new T[mCapacity];
}template<class T>
MaxHeap<T>::~MaxHeap()
{if (NULL != mHeap){delete[] mHeap;}mCapacity = 0;mSize = 0;
}template<class T>
void MaxHeap<T>::filterUp(int start)
{int cur = start;int par = (cur - 1) / 2;T tmp = mHeap[cur];while (cur > 0)       //注意此处退出循环条件:cur > 0{if (mHeap[par] >= tmp)break;mHeap[cur] = mHeap[par];cur = par;par = (cur - 1) / 2;}mHeap[cur] = tmp;
}template<class T>
void MaxHeap<T>::insert(T &data)
{if (mSize == mCapacity){cout << "insert error, cur heap is full now!" << endl;return;}mHeap[mSize] = data;filterUp(mSize);mSize++;      //先插入调整后,当前大小再加1
}template<class T>
void MaxHeap<T>::filterDown(int start, int end)
{int cur = start;int lch = 2 * cur + 1;T tmp = mHeap[cur];while (lch <= end){if (lch < end && mHeap[lch] < mHeap[lch + 1])lch++;if (tmp >= mHeap[lch]){break;}mHeap[cur] = mHeap[lch];cur = lch;lch = 2 * cur + 1;}mHeap[cur] = tmp;
}template<class T>
void MaxHeap<T>::remove(T &data)
{if (mSize == 0){cout << "remove error, cur heap is empty now!" << endl;return;}int index = getIndex(data);if (-1 == index){cout << "remove error, cur data is not in the heap!" << endl;return;}mHeap[index] = mHeap[--mSize];filterDown(index, mSize);      //先减小大小,再向下调整
}template<class T>
int MaxHeap<T>::getIndex(T &data)
{int index = 0;for (index = 0; index < mSize; index++){if (mHeap[index] == data)return index;}return -1;
}template<class T>
void MaxHeap<T>::print()
{for (int i = 0; i<mSize; i++)cout << mHeap[i] << " ";
}

测试代码如下:

void maxHeapTest(){int a[] = { 10, 40, 30, 60, 90, 70, 20, 50, 80 };int i, len = (sizeof(a)) / (sizeof(a[0]));MaxHeap<int>* tree = new MaxHeap<int>();cout << "== 依次添加: ";for (i = 0; i<len; i++){cout << a[i] << " ";tree->insert(a[i]);}cout << "\n== 最 大 堆: ";tree->print();i = 85;tree->insert(i);cout << "\n== 添加元素: " << i;cout << "\n== 最 大 堆: ";tree->print();i = 90;tree->remove(i);cout << "\n== 删除元素: " << i;cout << "\n== 最 大 堆: ";tree->print();cout << endl;delete tree;}

原文链接如下:https://www.cnblogs.com/skywang12345/p/3610382.html

二叉堆的实现(最大堆)相关推荐

  1. 2021-10-21 二叉堆 恋上数据结构笔记

    文章目录 引言:Top K问题 堆 二叉堆 二叉堆的实现原理 二叉堆的添加原理 二叉堆的删除 批量建堆(自上而下的上滤与自下而上的下滤)及其效率对比 引言:Top K问题 堆 二叉堆 二叉堆的实现原理 ...

  2. 二叉堆详解实现优先级队列

    二叉堆详解实现优先级队列 文章目录 二叉堆详解实现优先级队列 一.二叉堆概览 二.优先级队列概览 三.实现 swim 和 sink 四.实现 delMax 和 insert 五.最后总结 二叉堆(Bi ...

  3. 二叉堆简单实现与应用

    从二叉树谈二叉堆: 二叉树可以简单认为是父节点最多由左.右两个子节点组成的树,常用的二叉树有完全二叉树.二叉搜索树.二叉搜索树在极端境况下存在"跛脚"的问题,由此又有了二叉平衡树. ...

  4. 二叉堆 | 大根堆 小根堆

    目录 何为二叉堆 二叉堆的调整 最大堆 最大堆的插入操作 最大堆的删除操作 最大堆的构建 最大堆code 最小堆 小根堆的插入操作 最小堆的删除操作 最小堆的构建 最小堆code 二叉堆的存储方式 何 ...

  5. 动画 | 什么是二叉堆?

    点击蓝色"五分钟学算法"关注我哟 加个"星标",天天中午 12:15,一起学算法 来源 | 算法无遗策 二叉堆的解释 (动态选择优先级最高的任务执行) 堆,又称 ...

  6. 二叉堆算法具体实现细节- Java实现

    前言:之前在学习二叉堆算法时,感觉自己明白了.但是当我自己去写代码的时候,或者回想的时候,却很难系统的描述出来.在仔细研究源码之后,发现了一些之前没有发现的新东西,特地,记录下来,供大家参考. 文章目 ...

  7. 数组模拟实现二叉堆——(为以后的链表实现二叉堆打基础) _清风明月

    先开始抛出自己的测试数据啦. 9 344 23 5 6 45 3 7 89 1 3 First: (最优二叉树,哈弗曼树) 先把最小的两个选出来,然后让它们的和成为根节点的值,生成一棵新树,放进去.再 ...

  8. python最大堆_二叉堆 及 大根堆的python实现

    Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...

  9. 数据结构与算法--二叉堆(最大堆,最小堆)实现及原理

    二叉堆(最大堆,最小堆)实现及原理 二叉堆与二叉查找树一样,堆也有两个性质,即结构性质和堆性质.和AVL树一样,对堆的一次操作必须到堆的所有性质都被满足才能终止,也就是我们每次对堆的操作都必须对堆中的 ...

最新文章

  1. Python基于statsmodels包构建多元线性回归模型:模型构建、模型解析、模型推理预测
  2. 调试器定位变量的原理
  3. Dubbo 高危反序列化漏洞,存在远程代码执行风险,建议及时升级到2.7.7或更高版本!...
  4. 洛谷P1280 caioj 1085 动态规划入门(非常规DP9:尼克的任务)
  5. Spring Boot整合Spring Data Redis-存取JSON格式Java对象
  6. 音视频技术开发周刊(第120期)
  7. FATE HDU - 2159(二维完全背包)
  8. 和Hibernate3.6相比,Hibernate 5.x中的增删改性能降低了
  9. 集合、set、list、map、所有集合基本知识使用方法总结
  10. php助理工作内容,生产助理的工作职责
  11. 触动精灵怎么设置虚拟服务器,如何调试脚本及解决问题的方法
  12. fgo服务器维护补偿什么时候才有,FGO11月02日临时维护公告 补偿奖励一览
  13. 画计算机乐谱,邓紫棋《画》简谱
  14. STM32F103_study56_The punctual atoms(STM32 PWM output experimental code analysis)
  15. 2018/7/31-zznu-oj-问题 F: 手机密码--【裸dfs+for循环即可!——据说三个小时内只有两个人读完了题意并轻松AC了】...
  16. linux软路由设计博客,用Ubuntu来做个软路由
  17. 计算机考试设置背景音乐,给Excel表格添加背景音乐
  18. gif太大了怎么压缩?教你一招轻松压缩gif大小
  19. mysql是怎么实现多对多的_mysql复习篇及一对多和多对多的总结(17.6.26 )
  20. [Mysql] 防御和检查SQL注入攻击的手段

热门文章

  1. 气象ts评分_中国气象局广东省区域数值天气预报重点实验室
  2. 大学生c语言程序设计具体干什么,大学生c语言程序设计实习报告.doc
  3. 一页纸项目管理,附图表模板,可免费领取 | 再大的项目,都能用1页纸讲明白
  4. .Hisi 3516d_ov4689_5658调试
  5. ubuntu 系统连接 xiaomi手机
  6. pgsql时间处理的一些方式
  7. Prometheus 普罗米修斯
  8. 用Project软件编制项目计划【总结】
  9. Tanner L-Edit 系列教程:01 软件安装 - 附资源包
  10. html css js知识整理,Html+Css+Js实用知识汇总(持续更新中...)