Python heapq库的用法介绍

一、heapq库简介

heapq 库是Python标准库之一,提供了构建小顶堆的方法和一些对小顶堆的基本操作方法(如入堆,出堆等),可以用于实现堆排序算法。

堆是一种基本的数据结构,堆的结构是一棵完全二叉树,并且满足堆积的性质:每个节点(叶节点除外)的值都大于等于(或都小于等于)它的子节点。

堆结构分为大顶堆和小顶堆,在heapq中使用的是小顶堆:

1. 大顶堆:每个节点(叶节点除外)的值都大于等于其子节点的值,根节点的值是所有节点中最大的。

2. 小顶堆:每个节点(叶节点除外)的值都小于等于其子节点的值,根节点的值是所有节点中最小的。

在heapq库中,heapq使用的数据类型是Python的基本数据类型 list ,要满足堆积的性质,则在这个列表中,索引 k 的值要小于等于索引 2*k+1 的值和索引 2*k+2 的值(在完全二叉树中,将数据按广度优先插入,索引为k的节点的子节点索引分别为2*k+1和2*k+2)。在heapq库的源码中也有介绍,可以读一下heapq的源码,代码不多。

使用Python实现堆排序可以参考:https://blog.csdn.net/weixin_43790276/article/details/104033696

完全二叉树的特性可以参考:https://blog.csdn.net/weixin_43790276/article/details/104737870

二、使用heapq创建堆

# coding=utf-8
import heapqarray = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heap = []
for num in array:heapq.heappush(heap, num)
print("array:", array)
print("heap: ", heap)heapq.heapify(array)
print("array:", array)

运行结果:

array: [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heap:  [5, 7, 21, 15, 10, 24, 27, 45, 17, 30, 36, 50]
array: [5, 7, 21, 10, 17, 24, 27, 45, 15, 30, 36, 50]

heapq中创建堆的方法有两种。

heappush(heap, num),先创建一个空堆,然后将数据一个一个地添加到堆中。每添加一个数据后,heap都满足小顶堆的特性。

heapify(array),直接将数据列表调整成一个小顶堆(调整的原理参考上面堆排序的文章,heapq库已经实现了)。

两种方法实现的结果会有差异,如上面的代码中,使用heappush(heap, num)得到的堆结构如下。

使用heapify(array)得到的堆结构如下。

不过,这两个结果都满足小顶堆的特性,不影响堆的使用(堆只会从堆顶开始取数据,取出数据后会重新调整结构)。

三、使用heapq实现堆排序

array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heap = []
for num in array:heapq.heappush(heap, num)
print(heap[0])
# print(heapq.heappop(heap))
heap_sort = [heapq.heappop(heap) for _ in range(len(heap))]
print("heap sort result: ", heap_sort)

运行结果:

5
heap sort result:  [5, 7, 10, 15, 17, 21, 24, 27, 30, 36, 45, 50]

先将待排序列表中的数据添加到堆中,构造一个小顶堆,打印第一个数据,可以确认它是最小值。然后依次将堆顶的值取出,添加到一个新的列表中,直到堆中的数据取完,新列表就是排序后的列表。

heappop(heap),将堆顶的数据出堆,并将堆中剩余的数据构造成新的小顶堆。

四、获取堆中的最小值或最大值

array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heapq.heapify(array)
print(heapq.nlargest(2, array))
print(heapq.nsmallest(3, array))

运行结果:

[50, 45]
[5, 7, 10]

nlargest(num, heap),从堆中取出num个数据,从最大的数据开始取,返回结果是一个列表(即使只取一个数据)。如果num大于等于堆中的数据数量,则从大到小取出堆中的所有数据,不会报错,相当于实现了降序排序。

nsmallest(num, heap),从堆中取出num个数据,从最小的数据开始取,返回结果是一个列表。

这两个方法除了可以用于堆,也可以直接用于列表,功能一样。

五、使用heapq合并两个有序列表

array_a = [10, 7, 15, 8]
array_b = [17, 3, 8, 20, 13]
array_merge = heapq.merge(sorted(array_a), sorted(array_b))
print("merge result:", list(array_merge))

运行结果:

merge result: [3, 7, 8, 8, 10, 13, 15, 17, 20]

merge(list1, list2),将两个有序的列表合并成一个新的有序列表,返回结果是一个迭代器。这个方法可以用于归并排序。

六、heapq替换数据的方法

array_c = [10, 7, 15, 8]
heapq.heapify(array_c)
print("before:", array_c)
# 先push再pop
item = heapq.heappushpop(array_c, 5)
print("after: ", array_c)
print(item)array_d = [10, 7, 15, 8]
heapq.heapify(array_d)
print("before:", array_d)
# 先pop再push
item = heapq.heapreplace(array_d, 5)
print("after: ", array_d)
print(item)

运行结果:

before: [7, 8, 15, 10]
after:  [7, 8, 15, 10]
5
before: [7, 8, 15, 10]
after:  [5, 8, 15, 10]
7

heappushpop(heap, num),先将num添加到堆中,然后将堆顶的数据出堆。

heapreplace(heap, num),先将堆顶的数据出堆,然后将num添加到堆中。

两个方法都是即入堆又出堆,只是顺序不一样,可以用于替换堆中的数据。具体的区别可以看代码中的例子。

Python heapq库的用法介绍相关推荐

  1. Python binarytree库的用法介绍

    Python binarytree库的用法介绍 binarytree 库是一个 Python 的第三方库.这个库实现了一些二叉树相关的常用方法,使用二叉树时,可以直接调用,不需要再自己实现. 同时,b ...

  2. Python常用库的用法介绍都给大家整理出来啦,非常实用,建议收藏

    前言 随着大数据和人工智能的发展,Python也与多种科技深深绑定. 比如自动化测试,运维,爬虫,数据分析,机器学习,金融领域,后端开发,云计算,游戏开发都有涉及. 万丈高楼平地起,Python这座大 ...

  3. Python Pillow(PIL)库的用法介绍(二)

    Python Pillow(PIL)库的用法介绍(二) 在上一篇文章中介绍了Pillow库的一些基本用法,参考:https://blog.csdn.net/weixin_43790276/articl ...

  4. python 标准库之 glob 介绍(获取文件夹下所有同类文件)

    python标准库之glob介绍 glob 文件名模式匹配,不用遍历整个目录判断每个文件是不是符合. 1.通配符 星号(*)匹配零个或多个字符 import glob for name in glob ...

  5. [数据结构]Python Heapq库--小顶堆

    一.heapq库简介 heapq 库是Python标准库之一,提供了构建小顶堆的方法和一些对小顶堆的基本操作方法(如入堆,出堆等),可以用于实现堆排序算法. 堆是一种基本的数据结构,堆的结构是一棵完全 ...

  6. Python标准库glob用法精要

    Python标准库glob提供了glob()和iglob()两个函数用来枚举指定文件夹中符合特定模式的文件列表,支持"?"和"*"通配符. >>&g ...

  7. Python常用库及使用介绍

    python 库是参考其它编程语言的说法,就是指 python 中的完成一定功能的代码集合,供用户使用的代码组合. 在 python 中是包和模块的形式. 一般按照 API 的惯例来设计库. (1)p ...

  8. Python Requests库进阶用法——timeouts, retries, hooks

    Python HTTP 请求库在所有编程语言中是比较实用的程序.它简单.直观且在 Python 社区中无处不在. 大多数与 HTTP 接口程序使用标准库中的request或 urllib3. 由于简单 ...

  9. Python数组排序 lexsort函数用法介绍

    文章目录 前言 一.问题定义 二.方法讲解 1.基本思路 2.二维数组排序 三.Python List的基本操作 1. 删除 2.插入 总结 前言 最近开始对python语言做一点回顾,碰到一个二维数 ...

最新文章

  1. 计算机二级考试题未来教育里占多少,计算机二级笔试试题未来教育版.doc
  2. 学界 | 和清华大学自然语言处理与社会人文计算实验室一起读机器翻译论文
  3. oracle:sql约束
  4. [PHP] 算法-合并两个有序链表为一个有序链表的PHP实现
  5. 【2017年第2期】深度学习在化学信息学中的应用(下)
  6. A.2.5-输入年,月,判断本月有多少天?
  7. CIC滤波器的设计与仿真
  8. Spring实战(开发Web应用)
  9. 郑州调频广播频率表 转载
  10. windowsxp系统怎么装iis服务器,win xp系统安装IIS的详细步骤【图文】
  11. 【Linux】RHCE备考复习磁盘管理df、fdisk命令
  12. 1月英语总结—发现新大陆
  13. 什么叫同步,什么叫异步?
  14. hdu 4544 优先队列+贪心
  15. 六扇门风云/江湖风云录 4.07 宝箱 宝藏
  16. php 炸金花牌型 和 比牌 规则
  17. JSP实验-简单页面设计
  18. Delphi 微信支付接口AEAD_AES_256_GCM解密
  19. 织梦dedecms插件开发实例
  20. java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.

热门文章

  1. Ruby 101:重用、隐藏和多态
  2. Hive+LDAP+Sentry
  3. python 统计单词个数---从文件读取版本---不去重
  4. JSON返回的自定义
  5. [转载] 羽毛球——学打羽毛球 08 接发球 发球
  6. C#中静态构造函数的一些理解
  7. 容器编排技术 -- Kubernetes Replica Sets
  8. Docker安装Redis(docker-compose.yml)
  9. C语言,椰果数量问题,计算最少的椰果数
  10. Tomcat Post请求参数长度限制