关于python的内置堆

Python高级数据结构——堆(Heap) 堆是一种重要的数据结构,通过支持高效的插入和删除操作,在实际应用中发挥着重要作用。在Python中,可以使用heapq模块轻松实现堆。堆的应用场景包括优先队列和堆排序等。通过理解堆的基本概念、实现方式和应用场景,您将能够更好地运用堆解决实际问题。 阅读详情

1.简介

堆,又称优先队列,是一个完全二叉树,它的每个父节点的值都只会小于或等于所有孩子节点(的值)。 它使用了数组来实现:从零开始计数,对于所有的 k ,都有 heap[k] <= heap[2k+1] 和 heap[k] <= heap[2k+2]。 为了便于比较,不存在的元素被认为是无限大。 堆最有趣的特性在于最小的元素总是在根结点:heap[0]。

python的堆一般都是最小堆,与很多教材上的内容有所不同,教材上大多以最大堆,由于堆的表示方法,从上到下,从左到右存储,与列表十分相似,因此创建一个堆,可以使用list来初始化为 [] ,或者你可以通过一个函数 heapify() ,来把一个list转换成堆。如下是python中关于堆的相关操作,从这可以看出,python确实是将堆看作是列表去处理的。
在这里插入图片描述

2.堆的相关操作

heapq.heappush(heap, item)

将 item 的值加入 heap 中,保持堆的不变性。会自动依据python中的最小堆特性,交换相关元素使得堆的根节点元素始终不大于子节点元素。

原有数据是堆
import heapq

h = [1, 2, 3, 5, 7]
heapq.heappush(h, 2)
print(h)
#输出
[1, 2, 2, 5, 7, 3]

操作流程如下:

1.如下是初始状态
在这里插入图片描述

2.添加了2元素之后

在这里插入图片描述
3.由于不符合最小堆的特性,因此与3进行交换
在这里插入图片描述
4.符合最小堆的特性,交换结束,因此结果是[1, 2, 3, 5, 7, 3]

原有数据不是堆
import heapq

h = [5, 2, 1, 4, 7]
heapq.heappush(h, 2)
print(h)
#输出
[5, 2, 1, 4, 7, 2]

由此可见,当进行push操作时,元素不是堆的情况下,默认按照列表的append方法进行添加元素

heapq.heappop(heap)

弹出并返回 heap 的最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError 。使用 heap[0] ,可以只访问最小的元素而不弹出它。

原有数据是堆
import heapq

h = [1, 2, 3, 5, 7]
heapq.heappop(h)
print(h)
#输出
[2, 5, 3, 7]

操作流程如下:

1.初始状态
在这里插入图片描述

2.删除了堆顶元素,末尾元素移入堆顶
在这里插入图片描述

3.依据python最小堆的特性进行交换元素,由于7>2,交换7和2
在这里插入图片描述

4.依据python最小堆的特性进行交换元素,由于7>5,交换7和5
在这里插入图片描述

5.符合堆的要求,即结果为[2, 5, 3, 7]

原有数据不是堆
import heapq

h = [5, 2, 1, 4, 7]
heapq.heappop(h)
print(h)

[1, 2, 7, 4]

操作流程如下:

1.初始状态,很明显不符合堆的性质
在这里插入图片描述

2.移除最上面的元素(第一个元素),重新对剩下的元素进行堆的排列
在这里插入图片描述

3.依据python最小堆的特性,2>1 交换2与1
在这里插入图片描述

4.符合堆的要求,结果为[1, 2, 7, 4]

heapq.heappushpop(heap, item)

将 item 放入堆中,然后弹出并返回 heap 的最小元素。该组合操作比先调用 heappush() 再调用 heappop() 运行起来更有效率。需要注意的是弹出的元素必须位于堆顶或者堆尾,也就是说当插入一个元素后,进行比较最小元素时,其实一直比较的都是堆顶元素,如果插入元素大于或等于堆顶元素,则堆不会发生变化,当插入元素小于堆顶元素,则堆会依据python堆的最小堆特性进行处理。

原有数据是堆
import heapq

h = [1, 2, 3, 5, 7]
min_data = heapq.heappushpop(h, 2)
print(min_data)
print(h)
#输出
1
[2, 2, 3, 5, 7]

操作流程如下

1.初始状态
在这里插入图片描述
2.插入元素2
在这里插入图片描述

3.删除最小元素,刚好是堆顶元素1,并使用末尾元素2代替
在这里插入图片描述

4.符合要求,即结果为[2, 2, 3, 5, 7]

原有数据不是堆
h = [5, 2, 1, 4, 7]
min_data = heapq.heappushpop(h, 2)
print(min_data)
print(h)
min_data = heapq.heappushpop(h, 6)
print(min_data)
print(h)
#学习中遇到问题没人解答?小编创建了一个Python学习交流群:725638078

#输出
2
[5, 2, 1, 4, 7]
5
[1, 2, 6, 4, 7]

对于插入元素6的操作过程如下

1.初始状态
在这里插入图片描述
2.插入元素6之后
在这里插入图片描述

3.发现元素6大于堆顶元素5,弹出堆顶元素5,由堆尾元素6替换
在这里插入图片描述

4.依据python的最小堆特性,元素6>元素1且元素6>元素2,但元素2>元素1, 交换6与1
在这里插入图片描述

5.符合要求,则结果为[1, 2, 6, 4, 7]
由结果可以看出,当插入元素小于堆顶元素时,则堆不会发生改变,当插入元素大于堆顶元素时,则堆依据python堆的最小堆特性处理。

heapq.heapify(x)

将列表转换为堆。

h = [1, 2, 3, 5, 7]
heapq.heapify(h)
print(h)
h = [5, 2, 1, 4, 7]
heapq.heapify(h)
print(h)
#输出
[1, 2, 3, 5, 7]
[1, 2, 5, 4, 7]

会自动将列表依据python最小堆特性进行重新排列。

heapq.heapreplace(heap, item)

弹出并返回最小的元素,并且添加一个新元素item,这个单步骤操作比heappop()加heappush() 更高效。适用于堆元素数量固定的情况。

返回的值可能会比添加的 item 更大。 如果不希望如此,可考虑改用heappushpop()。 它的 push/pop 组合会返回两个值中较小的一个,将较大的值留在堆中。

import heapq


h = [1, 2, 3, 5, 7]
heapq.heapreplace(h, 6)
print(h)
h = [5, 2, 1, 4, 7]
heapq.heapreplace(h, 6)
print(h)
#输出
[2, 5, 3, 6, 7]
[1, 2, 6, 4, 7]
原有数据是堆

对于插入元素6的操作过程如下:
1.初始状态
在这里插入图片描述

2.弹出最小元素,只能弹出堆顶或者堆尾的元素,很明显,最小元素是1,弹出1,插入元素是6,代替堆顶元素
在这里插入图片描述

3.依据python堆的最小堆特性,6>2,交换6与2
在这里插入图片描述

4.依据python堆的最小堆特性,6>5,交换6与5
在这里插入图片描述

5.符合要求,则结果为[2, 5, 3, 6 ,7]

原有数据不是堆

对于插入元素6的操作过程如下:
1.初始状态
在这里插入图片描述

2.对于数据不为堆的情况下,默认移除第一个元素,这里就是元素5,然后插入元素6到堆顶
在这里插入图片描述

3.依据python的最小堆特性,元素6>1,交换元素6与1
在这里插入图片描述

4.符合要求,即结果为[1, 2, 6, 4, 7

heapq.merge(*iterables, key=None, reverse=False)

将多个已排序的输入合并为一个已排序的输出(例如,合并来自多个日志文件的带时间戳的条目)。 返回已排序值的 iterator。注意需要是已排序完成的可迭代对象(默认为从小到大排序),当reverse为True时,则为从大到小排序。

heapq.nlargest(n, iterable, key=None)

从 iterable 所定义的数据集中返回前 n 个最大元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 iterable 的每个元素中提取比较键 (例如 key=str.lower)。

等价于: sorted(iterable, key=key, reverse=True)[:n]。

import time
import heapq

h = [1, 2, 3, 5, 7]

size = 1000000
start = time.time()
print(heapq.nlargest(3, h))
for i in range(size):
    heapq.nlargest(3, h)
print(time.time() - start)

start = time.time()
print(sorted(h, reverse=True)[:3:])
for i in range(size):
    sorted(h, reverse=True)[:3:]
print(time.time() - start)
#输出
[7, 5, 3]
1.6576552391052246
[7, 5, 3]
0.2772986888885498
[7, 5, 4]

由上述结构可见,heapq.nlargest与sorted(iterable, key=key, reverse=False)[:n]功能是类似的,但是性能方面还是sorted较为快速。
heapq.nsmallest(n, iterable, key=None)

从 iterable 所定义的数据集中返回前 n 个最小元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 iterable 的每个元素中提取比较键 (例如 key=str.lower)。 等价于: sorted(iterable, key=key)[:n]。

import time
import heapq

h = [1, 2, 3, 5, 7]

size = 1000000
start = time.time()
print(heapq.nsmallest(3, h))
for i in range(size):
    heapq.nsmallest(2, h)
print(time.time() - start)

start = time.time()
print(sorted(h, reverse=False)[:3:])
for i in range(size):
    sorted(h, reverse=False)[:2:]
print(time.time() - start)
#输出
[1, 2, 3]
1.1738648414611816
[1, 2, 3]
0.2871997356414795

由上述结果可见,sorted的性能比后面两个函数都要好,但如果只是返回最大的或者最小的一个元素,则使用max和min最好。

3.堆排序

由于在python中堆的特性是最小堆,堆顶的元素始终是最小的,可以将序列转换成堆之后,再使用pop弹出堆顶元素来实现从小到大排序。具体实现如下:

from heapq import heappush, heappop, heapify


def heapsort(iterable):
    h = []
    for value in iterable:
        heappush(h, value)
    return [heappop(h) for i in range(len(h))]


def heapsort2(iterable):
    heapify(iterable)
    return [heappop(iterable) for i in range(len(iterable))]


data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]

print(heapsort(data))
print(heapsort2(data))
#输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

4.堆中元素可以是元组形式,主要用于任务优先级

from heapq import heappush, heappop

h = []
heappush(h, (5, 'write code'))
heappush(h, (7, 'release product'))
heappush(h, (1, 'write spec'))
heappush(h, (3, 'create tests'))
print(h)
print(heappop(h))
#学习中遇到问题没人解答?小编创建了一个Python学习交流群:725638078

[(1, 'write spec'), (3, 'create tests'), (5, 'write code'), (7, 'release product')]
(1, 'write spec')

上述操作流程如下:

1.当进行第一次push(5, ‘write code’)时
在这里插入图片描述

2.当进行第二次push(7, ‘release product’)时,符合堆的要求
在这里插入图片描述

3.当进行第三次push(1, ‘write spec’)时,
在这里插入图片描述

4.依据python的堆的最小堆特性,5>1 ,交换5和1
在这里插入图片描述

5.当进行最后依次push(3, ‘create tests’)时
在这里插入图片描述

6.依据python堆的最小堆特性,7>3,交换7与3
在这里插入图片描述

7.符合要求,因此结果为[(1, ‘write spec’), (3, ‘create tests’), (5, ‘write code’), (7, ‘release product’)],弹出元素则是堆顶元素,数字越小,优先级越大。

SGO基线解算软件(南方测绘UI设计最美观的一款新版) 不多说,先放地址: 下载地址:https://www.southgnss.com/download_view.asp?did=361 SGO是南方测绘集团广州南方卫星导航仪器有限公司自主研发新一代南方地理数据处理平台软件,对南方特有数据格式文件(STH格式文件)、标准数据格式文件(RINEX格式文件)进行静态数据处理、动态数据后处理和进行RTK结果检验,新增加了北斗数据处理和摄影测量模块,并围绕南方的不同类型测量产品集成多款测绘领域所需的小工具,实现测绘内业数据处理一体化。 相关概念 G.. 阅读详情

相关推荐

直流并联电压源的下垂控制与模拟光伏板特性的方法与仿真

并联直流电源下垂控制方法,下垂特性可以让并联直流电源输出功率/电流自动均衡,直流电源输出特性模拟光伏板的输出特性,具有自动限制输出最大功率的功能

1197

在 Python 中实现最小堆

树是一种非线性数据结构,其中元素排列在多个级别。堆是一种基于树的数据结构。它是一棵完全二叉树,即每个父节点都有两个子节点。堆实现不同的算法,对其他结构进行排序,对队列进行优先排序等。堆有两种类型 - 最大和最小。这些基于子节点与父节点相比的值。本篇文章将介绍最小堆及其在 Python 中的实现。

迹忆客 1567

独立游戏开发者必看:STEAM税务信息更新全流程(附中国区避坑指南)

本文为独立游戏开发者详细解析了Steam税务信息更新的全流程,重点针对中国区开发者提供了避坑指南。文章深入解释了W-8BEN表格的填写要点,并指导如何准备个人所得税纳税记录和身份证等核心证明文件,以确保顺利通过审核,避免收入被预扣税款。

tcp8optimizer的博客 1270

python中的堆(Heap)

堆(Heap)是一种特殊的完全二叉树数据结构,有两种类型:大顶堆和小顶堆。在大顶堆中,父节点的值大于或等于其子节点的值,而在小顶堆中,父节点的值小于或等于其子节点的值。堆作为一种重要的数据结构,在很多场景下提供了高效的解决方案。它具有良好的时间复杂度和灵活的应用性,因此在算法和软件开发中被广泛使用。库可以方便地进行堆的相关操作。除此之外,还可以自定义比较函数来实现大顶堆或特定要求的堆。库提供了一些函数来操作堆,如插入、删除和构建等。在Python中,可以使用。

jakelihua 4826

用Raspberry Pi Imager重装树莓派系统

这次在官网无意中看到他们出了一个Raspberry Pi Imager的工具,可以直接完成镜像烧录操作,于是就尝了个鲜。选择“编辑设置”按钮,会弹出具体的设置信息,有三个tab,第一个是General信息,包括用户名、密码、wifi和语言设置;后续的操作就和我当初第一次装树莓派系统的操作差不多,在此就不再赘述,有兴趣的朋友可以看我以前的博文。完成定制化设置后,点击“保存”按钮,软件回到前面的提示框,连续点击两个“是”,开始写入SD。第二个下拉框选择你要安装的OS,点击黄框所在的选项,可以挑选更多OS。

天飓的技术博客 1085

从零开始:用Python实现AlphaZero五子棋AI(附完整代码)

本文详细介绍了如何从零开始使用Python实现AlphaZero五子棋AI。通过工程化实践,逐步构建蒙特卡洛树搜索(MCTS)、轻量化残差网络(ResNet)以及自博弈训练循环,并提供完整可运行的代码。文章旨在帮助开发者绕过复杂理论,聚焦实战,最终打造一个能够自我学习与对弈的智能体,是深度强化学习在游戏AI领域的一次完整项目实战。

weixin_29081703的博客 415

【Python】一文带你学会数据结构中的堆、栈

栈(Stack)和堆(Heap)是计算机内存中常用的两种数据结构。它们在内存管理和数据存储方面具有不同的特点和用途。

Code_and516的博客 4034

C#读取CAD文件(dwg/dxf)并处理

项目要求识别CAD图纸(图纸内容与现实事物比例是1:1)中的内容,并提取出一些关键信息。这里的CAD图纸是指CAD文件,包含多种格式,dwg/dxf/dwf/stl/pdf等等。识别其中内容,主要指文件中的图元信息(也叫实体Entity),指线段、圆弧、矩形等图形元素。得到图元基础信息(比如长度、坐标、粗细)后,进一步做处理(如得到交点、得到线段间间隔、圆弧与线段切点等)。听起来有点难,因为作为软件工程师,对CAD相关事物并不了解,它是未知的;

三千幻想乡 1万+

Python语言的堆

堆是一种完全二叉树,满足堆的性质。具体来说:最大堆(Max Heap):对于堆中的每个父节点,其值大于或等于其子节点的值。最小堆(Min Heap):对于堆中的每个父节点,其值小于或等于其子节点的值。这种特性使得堆非常适合用于获取最大值或最小值的操作。尽管heapq模块提供了便利,但有时我们可能需要自定义堆的实现。下面是一个简单的堆的实现示例:```pythondefinit(self):= index:print("当前堆的最小元素:", min_heap.get_min())

2501_90990363的博客 1099

vue3 web项目引入高拍仪

高拍仪的引入步骤就两步,安装SDK,然后根据官网的api进行开发。根据自己需要的功能,请求对应的接口。

qq_42480170的博客 4115

WPF vs Avalonia: 跨入C#桌面应用现代化的大门

请注意,这只是一个目录,详细内容将根据这个结构逐步展开。如果您需要某个特定部分的详细内容,请告知我,我将为您提供深入的解析和示例代码。WPF,全称Windows Presentation Foundation,是微软为Windows平台量身打造的UI框架。自2006年发布以来,它就像一位经验丰富的老船长,引领着桌面应用的航船在技术的海洋中乘风破浪。Avalonia,一个新兴的跨平台UI框架,它像一位年轻的探险家,勇敢地探索着桌面应用的新世界。

java专栏 2398

python堆模块_python内置堆模块

heapqpython内置heapq模块,通过import heapq导入。heapq模块是用于堆实现优先队列。我们知道队列是先进先出(FIFO),heapq中的优先队列指的是不论谁先进,最小的先出或者最大的先出。# 需要注意的是heapq的堆是小根堆。01 23 4 5 ...

weixin_39559277的博客 145

华为OD机试双机位C卷-分披萨 (Py/Java/C/C++/Js/Go)

华为OD机试(机考)双机位C卷 【分披萨】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为od机试 - 分披萨。

qq_45776114的博客 1396

python 的内置模块堆 heapq

In [1]: import heapq In [2]...

weixin_33860737的博客 117

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

python堆模块_python 的内置模块堆 heapq

In [2]: h = []In [3]: h.append(1)In [4]: h.append(2)In [5]: h.append(3)In [6]: h.append(8)In [7]: h.append(5)In [8]: h.append(0)#用heapq 生成一个最小堆In [9]: heapq.heapify(h)In [10]: heapq.heappop()In [11]: ...

weixin_31302227的博客 189

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

用Python内置模块heapq实现堆

【代码】用Python内置模块heapq实现堆。

2403_84646142的博客 86

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

python堆模块_python:用heapq内置模块实现堆

上一篇文章我们用内置的collections.deque双端队列实现了栈和FIFO队列,以及用maxlen参数实现了取最后的N个元素的操作,但是除了简单队列,优先级队列---堆也是非常重要的一个数据结构,我们来看看如何用python实现吧。heapq模块实现堆:from heapq import heapify,heappush,heappop,nlargest,nsmallesta = list...

weixin_39616287的博客 263

python堆栈与队列_python内置的堆、栈和队列

本文用于介绍python中内置的堆、栈和队列结构方法,并且计较这些方法的差异与使用场景。heapq 堆队列heapq 是一个内置堆结构,一种特殊形式的完全二叉树,其中父节点的值总是大于子节点,根据其性质,python可以用一个满足 heap[k] ...

weixin_39604139的博客 584

算法题Python常用内置函数、方法、技巧汇总(其五:堆/优先队列)

60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁。谈到优先队列时,一般强调其功能或应用,谈到堆时,一般强调其树形结构,但这两个词是可以进行同义替换的,大部分时候不用做严格区分。每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!,在树形结构上体现为,每一个节点的值都小于其子节点的值。,在树形结构上体现为,每一个节点的值都大于其子节点的值。

weixin_48157259的博客 1461

Python中heapq堆的一些基本操作!!——————Python内置模块heapq(无需安装)

heapq堆 堆是非线性的树形的数据结构,有两种堆,最大堆与最小堆。( heapq库中的堆默认是最小堆) 最大堆,二叉树中各个父节点的值总是大于或等于任何一个子节点的值。 最小堆,二叉树中各个父节点的值总是小于或等于任何一个子节点的值。 我们一般使用二叉堆来实现优先级队列,它的内部调整算法复杂度为logN。 堆是一个二叉树,其中最小堆每个父节点的值都小于或等于其所有子节点的值。 整个最小堆的最小元素总是位于二叉树的根节点。 python的heapq模块提供了对堆的支持。 heap

Kinght_123的博客 1028

千问 “手动改写堆题目练习”通常是指在学习数据结构(尤其是堆/优先队列)时,不依赖语言内置的堆结构(如 Python 的 heapq、C++ 的 priority_queue),而是自己动手实现堆

下面我为你设计几个手动实现堆的练习题,由易到难,并附上简要提示或要求。如果你希望我提供某一道题的参考代码(比如 Python 实现),或者想把题目改成特定语言版本,请告诉我!提示:先找到元素位置(O(n)),将其与末尾交换,删除末尾,然后根据新值与父/子比较决定上浮或下沉。提示:用数组(列表)存储堆,根节点在索引 0;经典做法:先建最大堆,然后反复将堆顶与末尾交换,并缩小堆大小,再 sift_down。练习 4:支持删除任意元素的堆(可选进阶)练习 1:实现最小堆的基本操作。练习 2:从无序数组原地建堆。

m0_37843156的博客 388

python 内置速度最快算法(堆排)

import random import time from heapq import heappush, heappop def heapsort(iterable): h = [] for value in iterable: heappush(h, value) return [heappop(h) for i in range(...

weixin_34124577的博客 196
上一篇: Python函数中作用域教程
下一篇: python面向对象的组合和继承以及多继承
Python程序u猿
博客等级 码龄5年 622粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值