堆(数据结构)

什么是堆

堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象

堆的性质

这种用数组实现的二叉树,假设节点的索引值为index,那么:

节点的左孩子节点是 2*index+1,

节点的右孩子节点是 2*index+2,

左孩子节点的父节点是 (index-1) / 2。

右孩子结点的父结点是 (index-2) / 2

最大堆中,父结点的值比每一个子节点的值都要大

最小堆中,父结点的值比每一个子节点的值都要小

堆的插入,取值

堆是一种数据结构,分为最小堆和最大堆,可以用二叉树来表示。

在二叉树的任意的一个三角结构中(一个父节点,两个子节点),需要满足以下两个条件:

1、父节点要是最小的,就是最小堆(或最大的,就是最大堆),两个子节点之间没有要求

2、数据插入的顺序是一层一层的,只有上一层存满,才会有下一层

一、插入(insert)

假设我们有一个原始的最小堆如下:

插入操作:

当插入一个新值时,首先将值放到树的最后的位置,如下图所示。

然后将这个值与父级元素比较,如果不满足规则1,则与父元素替换(如下图所示)。

第一步

第二步

第三步

二、取值操作

取最小值操作:

在最小堆中,拿出一个最小值,当然就是拿出第一个数啦~不过拿完以后树不就没有“头”了?

不用担心,我们可以把最后一个数放到头的位置,这样树的结构就不会改变,而且操作简单(因为是最后一个数)并且不会改变完全二叉树结构。

当然,因为是最后一个数,必然会出现不满足条件1的情况,所以我们需要把新的树头与子元素比较替换,下面是图片演示:

假设我们有一个原始的最小堆如下所示,接下来我们要取最小值:

不过交换完很可能是不满足条件1的,那么我们就需要比较替换,替换规则是和两个子元素中最小的一个替换

由上面可以明白堆的插入与取值操作,那么我们接下来用代码实现最大堆的操作

最大堆实现操作步骤

首先创建一个堆的类

1、初始化一个空堆,使用数组来存放堆元素,节省存储

2、定义一个查找父结点的方法 get_parent_index 为插入,取值操作做准备

首先判断孩子结点下标:

当孩子结点下标为 0 时,证明此时孩子结点为根节点,根节点没有父结点,返回None

当孩子及诶点大于 当前堆的元素值时,证明此时没有该孩子结点,孩子结点不逊在,那么 该孩子结点没有父结点返回 None

当孩子结点有父结点时,利用位运算符 >> 求出当前孩子结点的父结点下标

3、定义交换两个索引值的方法 swap 方法,利用列表的下标,交换两个数值的位置

4、定义插入结点方法 insert 方法

先把元素放在最后面,然后往前依次堆化 (保证完全二叉树结构)
这里以大顶堆为例,如果插入元素比父结点大,则交换,直到最后

(1) 把新添加的结点插入数组的最后面

(2) 找到新添加(最后一个) 元素的索引

(3) 找到该元素的父结点下标

(4) 定义一个循环,判断当前孩子结点与父结点大小

若当孩子结点的值大于父结点时,不满足最大堆的条件,将孩子结点与父结点交换位置

交换后,子节点上移后,再次判断父结点下标,再次循环判断直到该元素成为堆顶,或小于父结点(对于大顶堆)

5、定义取值 删除堆顶元素 pop 方法

删除堆顶元素,然后将最后一个元素放在堆顶,在从上往下依次堆化,保证完全二叉树结构

(1) 找到堆顶元素

(2) 把最后一个结点放到堆顶

(3) 删除最后一个元素

(4) 从堆顶堆化,利用定义的 heapify 方法

(5) 返回删除的结点元素值

6、定义堆化 heapify 方法

从上往下堆化,从 index 开始堆化操作 (大顶堆)

最大堆代码实现

python

class Heap:def __init__(self):# 初始化一个空堆,使用数组来存放堆元素,节省存储self.data_list = []def get_parent_index(self,child_index : int): # child_index : 孩子结点下标"""返回父结点的下标"""if child_index == 0 or child_index > len(self.data_list) - 1:return Noneelse:return (child_index - 1) >> 1# 如果某个结点的孩子结点空缺,数组对应的位置也空缺# 假设一个父结点的下标是 parent ,左孩子的下标是  2*parent+1 ,右孩子下标是  2*parent+2# 左孩子的下标是 child,父结点的西下表是 (child - 1)/2def swap(self,index_a,index_b):'''交换两个索引对应的值:param index_a:  a索引:type index_a:  int:param index_b:  b索引:type index_b:  int:return::rtype:'''self.data_list[index_a],self.data_list[index_b] = self.data_list[index_b],self.data_list[index_a]def insert(self,data : int):"""先把元素放在最后面,然后往前依次堆化  (保证完全二叉树结构)这里以大顶堆为例,如果插入元素比父结点大,则交换,直到最后"""self.data_list.append(data) # 把新添加的结点插入数组的最后面curr_index = len(self.data_list) - 1 # 新添加(最后一个) 元素的索引curr_parent_index = self.get_parent_index(curr_index) # 找到该元素的父结点下标# 循环,直到该元素成为堆顶,或小于父结点(对于大顶堆)while curr_parent_index is not None and self.data_list[curr_parent_index] < self.data_list[curr_index]:self.swap(curr_parent_index,curr_index) # 利用 swap 交换操作curr_index = curr_parent_index # 结点上移curr_parent_index = self.get_parent_index(curr_parent_index) # 再次判断父结点def pop(self):"""删除堆顶元素,然后将最后一个元素放在堆顶,在从上往下依次堆化"""del_data = self.data_list[0] # 找到堆顶元素self.data_list[0] = self.data_list[-1] # 把最后一个结点放到堆顶del self.data_list[-1] # 删除最后一个元素self.heapify(0) # 从堆顶堆化,利用定义的 heapify 方法return del_data # 返回删除的元素def heapify(self,index):"""从上往下堆化,从 index 开始堆化操作 (大顶堆)"""size = len(self.data_list) - 1 # 数组的长度while True:mv_idx = index # mx_idx 代表最大值索引if 2 * index + 1 < size and self.data_list[2*index+1] > self.data_list[mv_idx]:mv_idx = 2 * index + 1 # 如果左孩子结点大于当前最大结点,最大值索引等于左孩子索引if 2 * index + 2 < size and self.data_list[2*index+2] > self.data_list[mv_idx]:mv_idx = 2 * index + 2 # 如果右孩子结点大于当前最大结点,最大值索引等于右孩子索引if mv_idx == index: # 如果当孩子结点与最大值索引相等时,证明此时循环完成,退出循环breakself.swap(mv_idx,index) #交换最大值和当前值index = mv_idx # 当前值等于这一轮的最大值结点if __name__ == '__main__':myheap = Heap()for i in range(10):myheap.insert(i + 1)print("建堆:",myheap.data_list)print("删除堆顶元素:",[myheap.pop() for i in range(10)])

dom4j实现为list添加父节点_Heap 堆的实现相关推荐

  1. dom4j实现为list添加父节点_最大堆的实现与原理

    本文主要讲的是实现最大堆,最小堆其实直接可以通过最大堆对比较运算做一定的处理,即可以得到. 同时可以参考 Java PriorityQueue 的实现. 堆可以作为优先队列.时间复杂度 O(logn) ...

  2. ztree 更新配置后重新渲染树_【问】zTree异步加载时添加父节点怎样避免再次加载整树...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 具体情况是 每当我执行add方法添加父节点的时候,都回去server端重新获取一次树节点信息,并加载在新增加的节点下. 页面代码如下 var settin ...

  3. unity查找子物体、子节点、获取子节点对象脚本,添加子节点脚本,添加父节点脚本

    分享一个代码管理片段的代码,主要是用于查找子物体,控制子物体等等的. 静态代码片段,便于调用. 不做太多的解释,直接上代码,每个方法都有注释. 有任何问题直接留言,看到会回复 QQ群 20701909 ...

  4. dom4j添加节点的父节点_HTML DOM节点介绍

    HTML DOM节点介绍,在HTML DOM中,所有事物都是节点.DOM是被视为节点树的HTML. DOM节点 根据W3C的HTML DOM标准,HTML文档中的所有内容都是节点: 整个文档是一个文档 ...

  5. sql server父节点_将新节点添加到现有SQL Server Always On可用性组中

    sql server父节点 This is the 5th article in the series of a comprehensive guide to SQL Server Always On ...

  6. XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 查找校验xml文件中相同的节点属性值 java遍历文件夹解析XML

    XML解析 (JAVA解析xml文件)java+Dom4j+Xpath xml文件解析根据子节点得到父节点 以及查找xml文件中相同的节点属性值 项目背景:这是本人实习中所碰到的项目,当时感觉很棘手, ...

  7. JavaScript 节点概述 、父节点 parentNode、子节点children、兄弟节点、创建节点 添加节点、删除节点、复制拷贝节点 ★案例★

    一般 节点至少拥有nodeType(节点类型).nodeName(节点名称)和nodeValue(节点值)这三个基本属性 元素节点 nodeType 为 1 属性节点 nodeType 为 2 文本节 ...

  8. qteewidgetitem添加子节点_行为树的节点

    一,行为树几大节点: Root节点:只能有一个子节点,并且该节点必须是" 复合"节点.不能将任何Decorator或Service附加到Root,在root可以指定其黑板资源: T ...

  9. 用父节点表示法表示一棵树

    今天学习,把书上的代码自己边对照,边敲了一下. package mytree;import java.util.ArrayList; import java.util.List;/*** 用父节点表示 ...

最新文章

  1. linux 网卡是块设备吗,什么是网络块设备(Network Block Device)?
  2. 第一章 SDN介绍 (附件2)【SDNNFV基础、云计算】
  3. 早上起来CSDN的PC端主页积分变成了0
  4. php curl 数据采集 空,PHP curl从网站返回空数组的数据
  5. Google Maps API 进级:在信息窗口GInfoWindow中嵌入Flash动画
  6. 翻译qmake文档(二) Getting Started
  7. Uncaught SyntaxError: Unexpected token ‘var‘
  8. jhipster初接触
  9. 智鼎逻辑推理题及答案_校园招聘在线测试笔试题型的种类和解题技巧
  10. python打开autocad软件_利用Python自动化操作AutoCAD的实现
  11. allegro的器件无法移动,而且右键点解锁没有用
  12. 弹幕视频网站的盈利模式 ——以哔哩哔哩弹幕网为例
  13. 2022年全国职业技能大赛网络安全竞赛试题B模块自己解析思路(2)
  14. 在使用单选、多选、下拉组件时,v-mode绑定的值的类型不准确引起显示报错注意
  15. dreamwever基础知识与简单网页的制作
  16. 自主实现小型的http服务器
  17. Reentrant mutex(递归锁)
  18. 当前行情下,真的还能“跳进”进大厂吗?
  19. 2019年微信市场饱和,公众号运营如何突出重围?黎想
  20. 拼多多2018年秋招提前批

热门文章

  1. c++ string类_C++|细说STL string类概貌及底层细节
  2. android背景不填充,(Android Studio)应用程序背景图像不填充屏幕
  3. 制表符空格数设置(阿里巴巴使用4个空格)
  4. Metricbeat添加ip address信息
  5. Haar特征与积分图—概念解析
  6. SpringMVC请求参数乱码问题
  7. vue错误:vue.esm.js?efeb:628 [Vue warn]: Error in render: “TypeError: Cannot read property ‘matched‘ of
  8. 树叶贴画机器人_洪山广场举办“落叶节”,树叶树枝拼贴出冬日风景
  9. java内部类练习题,学习笔记——Java内部类练习题
  10. rap2检测哪些接口在使用_Apifox for Mac(接口调试管理工具)