python中的堆

news/2025/1/8 20:38:26/文章来源:https://www.cnblogs.com/lmc7/p/18660516

在Python中,堆(Heap)是一种特殊的完全二叉树结构,满足以下特性:

  • 最大堆(Max Heap):父节点的值大于或等于子节点的值。
  • 最小堆(Min Heap):父节点的值小于或等于子节点的值。

Python标准库 heapq 提供了一个 最小堆 的实现,虽然没有直接提供最大堆的实现,但是可以通过一些技巧实现最大堆。

1. heapq 模块

heapq 是 Python 提供的堆相关操作的模块,它实现了一个最小堆。主要提供以下几个操作:

  • heapq.heappush(heap, item):将元素 item 添加到堆 heap 中。
  • heapq.heappop(heap):弹出堆中最小的元素并返回。
  • heapq.heapify(iterable):将可迭代对象 iterable 转换为堆。
  • heapq.heappushpop(heap, item):将元素 item 添加到堆中,并弹出最小元素。
  • heapq.heapreplace(heap, item):弹出堆中最小的元素并将元素 item 加入堆中。

2. 例子:最小堆操作

import heapq# 初始化堆
heap = []# 插入元素
heapq.heappush(heap, 10)
heapq.heappush(heap, 20)
heapq.heappush(heap, 15)# 弹出最小元素
print(heapq.heappop(heap))  # 10# 查看堆的最小元素但不弹出
print(heap[0])  # 15

3. 例子:最大堆的实现(通过取负值)

Python的 heapq 默认是最小堆,但可以通过取负数来模拟最大堆:

import heapq# 初始化最大堆
max_heap = []# 插入元素,取负值
heapq.heappush(max_heap, -10)
heapq.heappush(max_heap, -20)
heapq.heappush(max_heap, -15)# 弹出最大元素(实际上弹出的是最小负数,恢复负值后就是最大数)
print(-heapq.heappop(max_heap))  # 20

4. 堆排序

堆排序是通过堆来进行排序的,主要过程是先将数组转换为堆,再将堆顶元素弹出并将堆重新调整,直到所有元素都排好。

import heapqarr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]# 堆排序,首先将数组转为堆
heapq.heapify(arr)# 然后弹出堆顶元素,逐一得到排序后的结果
sorted_arr = [heapq.heappop(arr) for _ in range(len(arr))]print(sorted_arr)  # [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]

5. 常见算法题中的堆应用

5.1 寻找第K大的元素

给定一个无序的数组,找到第 K 大的元素。我们可以使用最小堆来解决这个问题。

import heapqdef findKthLargest(nums, k):# 构建一个包含前k个元素的最小堆heap = nums[:k]heapq.heapify(heap)# 遍历剩余元素for num in nums[k:]:# 如果当前元素大于堆顶元素(最小的元素)if num > heap[0]:heapq.heappushpop(heap, num)# 堆顶元素就是第K大的元素return heap[0]

5.2 合并K个排序链表

假设有多个已经排序的链表,合并它们。我们可以使用最小堆来解决这个问题。

import heapqclass ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextdef __lt__(self, other):return self.val < other.valdef mergeKLists(lists):heap = []# 初始化堆,将所有链表的头节点加入堆for l in lists:if l:heapq.heappush(heap, l)# 创建一个新的虚拟头节点dummy = ListNode()cur = dummy# 合并链表while heap:node = heapq.heappop(heap)cur.next = nodecur = cur.nextif node.next:heapq.heappush(heap, node.next)return dummy.next

5.3 查找前K个频繁元素

给定一个字符串,要求返回出现频率前K高的字符。

import heapq
from collections import Counterdef topKFrequent(nums, k):# 统计频率count = Counter(nums)# 使用最小堆存储频率和对应的元素heap = []for key, value in count.items():heapq.heappush(heap, (value, key))if len(heap) > k:heapq.heappop(heap)# 返回结果return [item[1] for item in heap]

6. 总结

  • Python 的 heapq 默认实现最小堆。
  • 可以通过插入负数来模拟最大堆。
  • 堆广泛应用于以下类型的问题:
    • 找到第 K 大/小的元素。
    • 合并多个排序序列。
    • 频率统计问题。

使用堆时可以通过适当的操作(如 heapq.heappushheapq.heappop)来高效地管理和访问数据结构中的最小或最大元素。

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

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

相关文章

mongodb windows zip安装并服务自启动

1.下载并解压。2.新建文件/文件夹 data/db 目录 logs/mongod.log 文件 conf/mongod.conf 文件 3.编辑conf/mongod.conf文件 systemLog:destination: filelogAppend: truepath: F:/mongodb-win32-x86_64-windows-6.0.20-rc3/logs/mongod.logstorage:dbPath: F:/mongodb-win32-x…

Linux通过端口找到对应的服务

首先执行netstat -tulnp | grep <端口号>例如:netstat -tulnp | grep :80参数解释:-t: 显示 TCP 连接(只显示TCP协议的端口信息)。 -u: 显示 UDP 连接(只显示UDP协议的端口信息)。 -l: 显示正在监听(Listening)状态的端口(只显示处于监听状态的端口)。 -n: 以数…

2025新春源码免费送

我们常常在日常生活中感到时间过得异常缓慢,仿佛未来遥不可及。然而,当我们回过头去审视过去,才发现时间早已悄然溜走,许多曾经等待的日子已经过去。时间总是在不经意间流逝,让人意识到它的宝贵和不可逆转。 尽管如此,我们依然应对未来保持从容的态度。生活充满了无数的可…

2025.1.8 鲜花

Nim 的变种Nim 的变种グランドエスケープ 空飛ぶ羽根と引き換えに 繋ぎ合う手を選んだ僕ら 没有选择飞翔的翅膀 而是选择十指相扣的我们 それでも空に魅せられて 夢を重ねるのは罪か 却仍然向往着天空 反复做着同样的梦 这有错吗 夏は秋の背中を見て その顔を思い浮かべる 夏…

CTF 之 Crypto (Cryptography) 学习笔记

CTF 之 Crypto (Cryptography) Chapter 0. 前置知识 群 (Group) 给定一个集合 \(G\neq \emptyset\) 以及二元代数运算 \(\circ\),若满足:封闭性 (Closure):\(\forall u,v\in G\),\(u\circ v\in G\); 结合律 (Associativity):\(\forall u,v,w\in G\),\((u\circ v)\circ w…

(2025自测有效!)全网最好的python配置教程【非常非常适合小白】

前几天我的电脑刚刚重装,把python重新配置了一下。 1.Python环境部署Python3 可应用于多平台包括 Windows、Linux 和 Mac OS X。 Python官网:https://www.python.org/ 进入官网在导航栏选择Dowmloads,选择所使用的系统(以Windows为例) 进入Windows下载页之后选择需要下载的…

写一个支持折叠、有缩进、代码高亮、离线的,方便部署的、易用的、优雅的json格式化查看工具(附html完整代码)

缘由 网上的在线json格式化有很多,但我是个有追求的人。在线的很难同时支持折叠、有缩进线、代码高亮、离线的,方便部署的、易用的、不请求后端(为了安全)的json格式化工具。 去Github上找项目,华而不实的东西占半个屏幕,格式化json要点好几下,一个json格式化工具npm安装…

AGC041F Histogram Rooks

我不知道啊,我只是觉得容斥很好玩。一个朴素的想法是容斥:考虑钦定 \(S\) 集合的位置没有被车覆盖,则答案是 \((-1)^{|S|}2^{c}\),其中 \(c\) 是可以放车的位置,可以直接 dp 做到 \(\mathrm{O}(2^n \text{poly}(n))\),但是难以优化。 延续容斥的想法,注意到钦定一个位置…

rust学习十六.1、并发-乱弹和一个简单并发例子

如书本作者所言,并发编程在绝大部分语言中,都是相对复杂和困难的。 所以,涉及的内容会相对多一些,所涵盖的内容绝对不是几篇文章所可以容纳的。 权当一个乱弹琴! 和此系列的其它文章一样,本文的内容绝大部分来自于相关书籍,本人做了一些摘裁的工作,取我所需!一、无畏并…

解决jenkins git 拉取代码超时问题

jenkins默认的是时间是10分钟,在git fetch时候超过10分钟了就报错失败了,可在项目源码管理 新增 advance clone behaviours

Java Bluetooth 蓝牙通讯 BlueCove 扫描附近的蓝牙设备

目录BlueCove项目概述BlueCove API架构API的设计原则和实现方式关键类和方法的功能描述测试代码获取本机(PC)蓝牙扫描蓝牙 BlueCove项目概述 BlueCove是一个开源的蓝牙协议栈实现,旨在为Java开发者提供一个全面的、易于使用的API,从而在应用程序中实现蓝牙功能。该项目支持多…