数据结构与算法(6) -- heap

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

binaryHeap.png?raw=true

以上是一个对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的位置,则上浮结束。
push_heap.png?raw=true

一个简易的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. 将第一个元素/根元素下沉到一个合适的位置。注意下沉的时候是与子节点较大的那个元素交换。
pop_heap.png?raw=true

一个简易的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

涂鸦WIFI模组方案(MCU SDK)

摘自涂鸦官方视频教程&#xff1a;https://www.bilibili.com/video/BV1pb41117LD?spm_id_from333.999.0.0等 摘自&#xff1a;涂鸦IoT开发平台MCU开发接入(Wi-Fi)-App面板 地址&#xff1a;https://www.bilibili.com/video/BV1cK4y1x7Up?spm_id_from333.999.0.0 摘自&#xf…

MySQL数据库添加一个字段

MySQL数据库添加一个字段 1、添加一个字段 alter table tableName add 列名 数据类型; 2、添加一个字段设置默认值 alter table tableName add 列名 数据类型 default 0; &#xff08;注&#xff1a;这里设置默认值为0&#xff09; 例子&#xff1a;在users表添加一个int类型…

研究方向

企业软件可以研究的东西实在太多了&#xff0c;从C#的语法细节&#xff0c;底层实现机制到设计模式从全局把握&#xff0c;从微观的页面设计到宏观的性能调整&#xff0c;从具体的编程技巧到具体的事例研究&#xff0c;如此种种。 前两个星期&#xff0c;一个星期抱着《设计模式…

SVN使用教程

摘自&#xff1a;SVN使用教程 地址&#xff1a;https://www.bilibili.com/video/BV1k4411m7mP?fromsearch&seid1516107384812084869&spm_id_from333.337.0.0 摘自&#xff1a;快速掌握Git分布式系统操作 地址&#xff1a;https://www.bilibili.com/read/cv14701783?s…

机器学习sklearn的快速使用--周振洋

ML神器&#xff1a;sklearn的快速使用 传统的机器学习任务从开始到建模的一般流程是&#xff1a;获取数据 -> 数据预处理 -> 训练建模 -> 模型评估 -> 预测&#xff0c;分类。本文我们将依据传统机器学习的流程&#xff0c;看看在每一步流程中都有哪些常用的函数以…

今日个人大事记:)

1、拿到一台1G DDR2内存的电脑&#xff0c;终于可以把虚拟内存设为0了&#xff0c;呵呵。 2、试用了下MS的Virtual Server 2005&#xff0c;发现Client连接可以在Web上或使用应用程序&#xff0c;而虚拟机器配置是在Web上&#xff0c;不大方便。似乎不太符合MS一惯的作风啊。 3…

自动添加注释

程式的时候给代码注释有时候蛮烦人的&#xff0c;尤其是用英文写注释的时候&#xff0c;但是养成写注释的习惯&#xff0c;对日后代码的维护还是很有帮助的&#xff0c;一般脚本的开头会注明编写时间&#xff0c;版本&#xff0c;用途等说明。VIM 里面能够使用映射(map)来帮您自…

太极创客ESP8266 - NodeMCU、JSON、MQTT教程(基于Arduino)

太极创客ESP8266视频教程&#xff1a;https://www.bilibili.com/video/BV1L7411c7jw?fromsearch&seid4858784806004995732&spm_id_from333.337.0.0 官网资料&#xff1a;http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-iot-basics/ 太极创客…

Voltage Keepsake CodeForces - 801C (思维+二分)

题目链接 这是一道很棒的二分题。 思路&#xff1a; 首先先思考什么情况下是可以无限的使用&#xff0c;即输出-1. 我们思考可知&#xff0c;如果每一秒内所有设备的用电量总和小于等于充电器每秒可以充的电&#xff0c;那么这一群设备就可以无限使用。 接下来分析不是无限使用…

Linux网络服务-LAMP之Php基于Apache的模块实现

一、概述 首先&#xff0c;如标题所示我接下来的实验就是搭建一个LAMP平台然后实现一个Blog站点的实现&#xff0c;那"Php基于Apache的模块实现"这又是神马意思呢&#xff0c;我们知道Apache与Php的结合方式有常见的三种&#xff1a;基于module、基于CGI、基于Fa…

4G DTU使用教程

摘自&#xff1a;https://www.bilibili.com/video/BV1uP4y187bw?spm_id_from333.999.0.0 目录了解4G DTUATK - M750模组使用NET模式(网络透传)使用HTTP模式使用阿里云透传模式使用百度云透传模式使用OneNET模式透传模式了解4G DTU 4G DTU对比传统的4G模组更简单易用&#xff…

Kalman Filter

原理介绍 https://pan.baidu.com/s/15zDz8TeM8PKMsH231a0fOw 简单的例子 https://www.jianshu.com/p/d3b1c3d307e0 下图中“对应例子”就是所引用简书博客提到的例子。预测-校正交替运行。 博客&#xff1a;自动驾驶基础之——如何写卡尔曼滤波器&#xff1f; https://mp.weixi…

专注

"选择不做一件事情,有时候比做更难."我很喜欢这句话,一个公司要专注于自己的项目.即使对于一个项目而言,也要专注.因为公司发展初期各种资源是有限的,必须把资源集中在一点上.但有时候项目的定位牵扯到项目的战线问题.既要达到定位,又要控制利用好自己的资源,这个确实…

移远EC20 4G模块LTE开发板三网通模块 MQTT阿里云物联网

摘自&#xff1a;移远EC20 4G模块LTE开发板三网通模块 MQTT阿里云物联网STM32代码-电脑看 地址&#xff1a;https://www.bilibili.com/video/BV1EJ411P7CR?fromsearch&seid6590774415258771438&spm_id_from333.337.0.0 摘自&#xff1a;STM32开发板NB-IOT移远BC26 NB模…

在 LinearLayout里addView一个图表

2019独角兽企业重金招聘Python工程师标准>>> activity_main.xml <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"fill_parent"and…

准备写个nhibernate的学习笔记

经理说要用这个做数据层管理。先找点资料 C C 先&#xff5e;&#xff01; 有心得就慢慢贴上来转载于:https://www.cnblogs.com/marsforest/archive/2005/04/19/140670.html

Home Assistant 安装Samba和SSH server 插件

安装 Samba 插件 Samba 是 SMB/CIFS 网络协议的重新实现, 它作为 NFS 的补充使得在 Linux 和 Windows 系统中进行文件共享、打印机共享更容易实现。 Smaba 服务是必装的一个插件&#xff0c;Hass.io 通过它与局域网内的其他设备进行文件共享&#xff0c;是之后编辑 Hass.io 配置…

涂鸦WIFI模组方案(模组 SDK)

摘自&#xff1a;涂鸦智能模组 SDK 开发系列课程 地址&#xff1a;https://www.bilibili.com/video/BV1Kq4y1o728?p1 摘自&#xff1a;涂鸦智能模组SDK开发系列课程——Wi-Fi接入 地址&#xff1a;https://blog.csdn.net/sandwich_iot/category_11289915.html?spm1001.2014.3…

IOS静态库生成及测试

目录&#xff1a;1 生成静态库(.a文件)2 测试静态库文件1 生成静态库文件&#xff1a;1.1创建静态库项目static_library1.2 添加方法&#xff1a; - (int)getMax:(int)a b:(int)b;-(int)getMin:(int)a b:(int)b;(void)print;实现这些方法1.3 编译前选择IOS Device和模拟器&am…

整几个题给大家玩玩,看看“下盘功夫”怎样

不用编译器&#xff0c;回复你的答案。 感觉现在很多程序员老在追遂各种各样的新名词、新术语&#xff0c;别人把几个英语单词整一块&#xff0c;取出第一个字母&#xff0c;X除外&#xff0c;这年头&#xff0c;X牛啊&#xff0c;不在第一也优先取它&#xff0c;然后好像记住…