binary heap就是一种complete binary tree(完全二叉树)。也就是说,整棵binary tree除了最底层的叶节点之外,都是满的。而最底层的叶节点由左至右又不得有空隙。

以上是一个对heap的简单介绍。本文将用heap指代此种完全二叉树。那么在实际编写代码的时候怎么组织这种数据呢,其实可以用array来存储这种结构的数据。将数组的第0个元素保留不用,从第一个元素开始存放数据。那么,对于树中的某个位于i的节点,其左子节点必然位于2i处,右子节点必然位于2i+1处,父节点必然位于“i/2”处。当然heap要能动态的改变大小,所以用vector存储数据会更好。

这里还有一个小的细节需要注意一下,heap可以分为max-heap以及min-heap,前者每个节点的键值都大于或等于其子节点键值,后者的每个节点键值都小于或等于其子节点键值。可以推出,max-heap的最大键值在根节点,min-heap的最小键值在根节点。

综上:heap就是一个包含了一组数据(通常可用array/vector来存储)以及一组管理这些数据的算法(插入元素,删除元素,取极值,将一组数据排列成一个heap)。通过这些方法可以保证heap的特性。

heap的算法

因为在c++ stl中并不直接提供heap这样一种数据结构,但它却是很多数据结构的基础:例如优先队列。所以这里我们主要关注的是heap涉及到的一些算法。

push_heap

在很多书籍当中,通常通过一个上浮的操作来完成push_heap。其基本原理可见下图(假设新加入的元素是50):

  1. 将50插入到数组的末尾。
  2. 将其于父元素相比较,发现24小于50,交换这两个元素。上浮一次
  3. 继续上述操作直到找到一个合适的位置,也即其父元素大于50的位置,则上浮结束。

一个简易的c++实现:

template<typename T>
void push_heap(std::vector<T> &vec, T value)
{vec.push_back(value);int i = vec.size()-1;while (i > 1 && vec[i] > vec[i / 2]) {std::swap(vec[i], vec[i / 2]);i = i / 2;}
}

pop_heap

pop操作是类似的:

  1. 将最后一个元素与第一个元素(根元素)交换。
  2. 删除最后一个元素。
  3. 将第一个元素/根元素下沉到一个合适的位置。注意下沉的时候是与子节点较大的那个元素交换。

一个简易的c++实现:

template<typename T>
T pop_heap(std::vector<T> &vec)
{int i = 1;//将最后元素与第一个元素(根元素)交换, 然后删除最后一个元素std::swap(vec[1], vec[vec.size() - 1]);T v = vec[vec.size() - 1];vec.pop_back();//将现在的第一个元素/根元素下沉到一个合适的位置while (2 * i < vec.size()) {int j = 2 * i;  //左子节点if (j < vec.size() - 1 && vec[j] < vec[j + 1]) j++;if (vec[j] < vec[i]) break;std::swap(vec[i], vec[j]);i = j;}return v;
}

sort_heap

sort_heap是利用heap每次都取出极值(这里是max)的特性进行排序。那么只要进行n次pop_heap即可完成排序。

template<typename T>
void sort_heap(std::vector<T> &vec)
{std::vector<T> temvec;int size = vec.size()-1;while (size != 0) {temvec.push_back(pop_heap(vec));size--;}for (T value : temvec) {vec.push_back(value);}
}

See you next time. Happy Coding!!!
我的github

转载于:https://www.cnblogs.com/dnhua/p/10224731.html

数据结构与算法(6) -- heap相关推荐

  1. 数据结构与算法笔记:贪心策略之BSTBBST, Hashtable+Dictionary+Map, Priority Queue~Heap, Minium Spanning Tree

    BST & BBST BST(Binary Search Tree) 二叉搜索树,也就是使用二叉树来做查找 BBST(Balanced Binary Search Tree) 平衡二叉搜索树 ...

  2. Python3-Cookbook总结 - 第一章:数据结构和算法

    第一章:数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. ...

  3. 「走过」微软、优步,老工程师告诉你哪些数据结构和算法最重要

    数据结构和基础算法作为计算机科学的必学课程,近几年却关注度越来越少.但程序员真的不再需要这两门基础知识了吗?一位在 Uber 等科技公司工作过的开发者分享了他的一手经验,告诉你实际工作中会用到哪些数据 ...

  4. Java数据结构与算法——树(基本概念,很重要)

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 有网友私信我,期待我的下一篇数据结构.非常荣幸文章被认可,也非常感谢你们的监督. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督 ...

  5. 数据结构与算法(4)——优先队列和堆

    前言:题图无关,接下来开始简单学习学习优先队列和堆的相关数据结构的知识: 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) ...

  6. 买什么数据结构与算法,这里有:动态图解十大经典排序算法(含JAVA代码实现)

    上篇的动图数据结构反响不错,这次来个动图排序算法大全.数据结构与算法,齐了. 几张动态图捋清Java常用数据结构及其设计原理 本文将采取动态图+文字描述+正确的java代码实现来讲解以下十大排序算法: ...

  7. 数据结构常见算法集锦

    数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...

  8. 数据结构经典算法集锦

    数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...

  9. 数据结构与算法 Big O 备忘录与现实

    不论今天的计算机技术变化,新技术的出现,所有都是来自数据结构与算法基础.我们需要温故而知新. 算法.架构.策略.机器学习之间的关系.在过往和技术人员交流时,很多人对算法和架构之间的关系感到不可理解,算 ...

最新文章

  1. 扎克伯格曝光Meta的小目标:AI自动生成元宇宙,实时翻译所有语言
  2. 人生苦短,我用python,为什么选择python,python简介
  3. 在线JSON转sarcastic工具
  4. Web前端性能优化的9大问题
  5. android 长截屏实现,Android实现截屏与截长图功能
  6. 最小二乘法-线性拟合
  7. 百度CNZZ统计留痕引流工具 日引流过万ip
  8. 浅谈代理服务器的作用
  9. 小米忙着营销,麻烦带上技术!
  10. 一键u盘装系统ghost win7 64位教程
  11. 智能眼镜是头戴式摄像机
  12. 索骥馆-网络创业之《网上赚钱从入门到精通》扫描版[PDF]
  13. Touchpad驱动分析——转载
  14. PLL为什么可以倍频
  15. java截取字符串可用于截取文件后缀名
  16. MPU6050(读取原数据、移植DMP、stm32f4、HAL库、KEIL5)
  17. [Android开发那点破事]解决android.os.NetworkOnMainThreadException
  18. mattermost之数据库操作
  19. 关于leaflet开源库的学习
  20. Inception网络(Inception Network)

热门文章

  1. 五个常用的Linux监控脚本代码
  2. SlidingMenu的使用,结合Fragment(eclipse环境)
  3. cf13C Sequence(DP)
  4. mongoose --- 建立一个集合规则,并导出.
  5. 面试时,面试官到底在考察什么?
  6. centos7搭建FTP服务器
  7. NFS精简版配置方法
  8. Cesium应用篇:3控件(3)SelectionIndicator InfoBox
  9. linux删除、读取文件原理
  10. android获取控件宽度高度