数据结构与Python——堆(heap)

本文介绍了堆的性质,包括最大堆和最小堆的概念,堆与二叉搜索树的区别,以及堆在内存和平衡方面的特点。重点讲解了Python中heap模块的实现,如heappush、heapify、heapreplace等函数的使用,并展示了使用heap模块查找最大值和最小值的高效方法。
摘要由CSDN通过智能技术生成

一、堆是什么


堆是用数组实现的二叉树,所以它没有父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。
堆的一般用法:
.构建优先队列
.支持堆排序
.快速查找出集合的最大值或者最小值

二、堆属性


堆分为最大堆(max heap)和最小堆(min-heap),两者的差别在于节点的排序方式。

最大堆中,父节点的值比每个子节点的值都要大,最小堆中,父节点的值比每一个子节点的值都要小。这就是所谓的“堆属性”(heap property),并且这个属性对堆中每一个节点都成立。
举个栗子:
堆属性
这是一个最大堆,因为每一个父节点的值比子节点的值都要更大。10 比 7 和 2 都打,7比5 和1 都大。
根据这一属性,那么最大堆总是将其中的最大值存放在树的根节点。而对于最小堆,根节点中的元素总是树中的最小值。堆属性非常的有用,因为堆常常被当做优先队列使用,因为可以快速的访问到“最重要”的元素。

注意:堆的根节点中存放的是最大或者最小元素,但是其他节点的排序顺序是未知的。
例如,在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的
元素则未必是最后一个元素。--唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。

2.1 堆和普通树的区别
堆不能取代二叉搜索树,它们之间确有一些相似的地方,但是又有一些不同的地方,下面是一下主要的不同之处。
1.节点的顺序。在一个二叉搜索树(BST)里面,左边的子节点必须小于父节点,右边的子节点必须大于子节点。但是在堆里面并非如此,在最大堆里面,所有子节点必须比父节点的值更小,最小堆里面则相反。
2.内存的占用,普通树占用的内存空间比他们实际存储的数据更多,你必须为节点对象以及左/右子节点指针分配额外的存储空间,而堆只用一个普通的数组结构来存储,并不会用到指针。
3.平衡,一个二叉树必须要在平衡的情况下,其大部分操作的时间复杂度才能保持在O(logn), 你可以以任意的顺序插入和删除数据,或者使用AVL树或者红黑树,但是在堆里面,我们不用保证整个树是有序的状态。我们只需要堆属性被实现即可,所以堆中平衡不是问题。因为堆的结构,所以保证O(log n)的性能。
4.搜索。在二叉搜索树里面搜索会很快,但是在堆中会很慢,因为堆的目的是把最大或者最小节点前置以及保证插入和删除相对快 所以搜索对于堆而言优先级并不是最高的。

**

来自数组的树

**

用数组来展示树状的结构可能看起来很奇怪,当时在时间和空间上都是很高效。
接下来我们来展示举个栗子:

[10,7,2,5,1]

就这么多,除了简单的数组以外,我们并不需要更多的存储空间。
那么,在不被允许使用指针的情况下我们如何知道那个节点是父节点,哪个是子节点呢?问得好!节点在数组中的位置index和它的父节点和子节点之间存在一个映射关系。
如果i是节点的索引,那么下面的公式就给出了父节点以及子节点在数组中的位置。

parent(i) = floor((i-1)/2)
left
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值