当前位置: 首页 > news >正文

Python堆与优先队列

Python堆与优先队列 — heapq模块/最大堆/K路合并/中位数查找堆是一种完全二叉树结构Python的heapq模块实现的是最小堆。堆常用于优先队列、Top-K问题、任务调度等场景。1. heapq 基本操作import heapq# heapq提供对Python列表的就地堆操作data [5, 3, 8, 1, 9, 2]heapq.heapify(data) # 将列表转换为最小堆原地操作print(最小堆:, data) # [1, 3, 2, 5, 9, 8]# heappush: 向堆中插入元素保持堆性质heapq.heappush(data, 0)print(插入0后:, data) # [0, 3, 1, 5, 9, 8, 2]# heappop: 弹出并返回堆顶元素最小值smallest heapq.heappop(data)print(弹出最小值:, smallest) # 0print(弹出后:, data)# heappushpop: 先push再pop比先后调用更高效result heapq.heappushpop(data, -1)print(pushpop结果:, result) # -1堆中最小值被弹出# heapreplace: 先pop再push与pushpop相反result heapq.heapreplace(data, 10)print(replace结果:, result)2. nlargest / nsmallest — Top-K 问题scores [42, 67, 13, 89, 55, 90, 24, 71, 88, 33]top3 heapq.nlargest(3, scores) # 获取最大的3个元素print(Top 3:, top3) # [90, 89, 88]bottom3 heapq.nsmallest(3, scores) # 获取最小的3个元素print(Bottom 3:, bottom3) # [13, 24, 33]# nlargest和nsmallest也支持key参数用于复杂对象的比较students [(Alice, 88), (Bob, 95), (Charlie, 72), (David, 91)]top_students heapq.nlargest(2, students, keylambda s: s[1])print(分数最高的两名学生:, top_students) # [(Bob, 95), (David, 91)]3. 模拟最大堆Max-Heapclass MaxHeap:Python的heapq只支持最小堆通过存入负值来模拟最大堆def __init__(self):self._data [] # 实际存储负值的堆def push(self, val):heapq.heappush(self._data, -val) # 存入负值def pop(self):return -heapq.heappop(self._data) # 弹出后取反def peek(self):return -self._data[0] if self._data else Nonedef __len__(self):return len(self._data)max_heap MaxHeap()for v in [3, 1, 4, 1, 5, 9]:max_heap.push(v)print(最大堆弹出:, max_heap.pop()) # 9print(最大堆弹出:, max_heap.pop()) # 54. 自定义比较器的优先队列import dataclassesdataclasses.dataclass(orderTrue)class Task:任务类优先级高的先执行priority: int # 数值越小优先级越高name: str dataclasses.field(compareFalse) # 不参与比较# 直接使用heapq存储Task对象tasks [Task(3, 写报告), Task(1, 修复Bug), Task(2, 开晨会)]heapq.heapify(tasks)while tasks:t heapq.heappop(tasks)print(f执行任务: {t.name} (优先级{t.priority}))# 输出顺序: 修复Bug - 开晨会 - 写报告5. 合并K个有序列表def merge_k_sorted_lists(lists):使用堆合并K个有序列表时间复杂度O(NlogK)heap []# 将每个列表的头元素值和所在列表索引、元素索引加入堆for i, lst in enumerate(lists):if lst:heapq.heappush(heap, (lst[0], i, 0))result []while heap:val, list_idx, elem_idx heapq.heappop(heap)result.append(val)# 如果该列表还有下一个元素将其加入堆if elem_idx 1 len(lists[list_idx]):next_val lists[list_idx][elem_idx 1]heapq.heappush(heap, (next_val, list_idx, elem_idx 1))return resultlists [[1, 4, 7], [2, 5, 8], [3, 6, 9]]print(合并K个有序列表:, merge_k_sorted_lists(lists)) # [1,2,3,4,5,6,7,8,9]6. 中位数查找双堆法class MedianFinder:使用最大堆最小堆维护数据流的中位数def __init__(self):self.small [] # 最大堆存较小的一半用负值模拟self.large [] # 最小堆存较大的一半def add_num(self, num):插入新数字if not self.small or num -self.small[0]:heapq.heappush(self.small, -num)else:heapq.heappush(self.large, num)# 平衡两个堆的大小保证small比large多0或1个元素if len(self.small) len(self.large) 1:heapq.heappush(self.large, -heapq.heappop(self.small))elif len(self.large) len(self.small):heapq.heappush(self.small, -heapq.heappop(self.large))def find_median(self):返回当前中位数if len(self.small) len(self.large):return -self.small[0] # 奇数个small堆顶就是中位数return (-self.small[0] self.large[0]) / 2.0 # 偶数个取平均mf MedianFinder()for v in [5, 2, 8, 1, 9]:mf.add_num(v)print(f添加{v}后中位数: {mf.find_median()})7. 任务调度器模式def least_interval(tasks, n):任务调度器相同任务之间至少间隔n个时间片freq [0] * 26for t in tasks:freq[ord(t) - ord(A)] 1max_freq max(freq) # 出现次数最多的任务的频率max_count freq.count(max_freq) # 有多少种任务出现了max_freq次part_count max_freq - 1 # 间隔段数part_length n 1 # 每段的长度empty_slots part_count * part_length # 总的理论插槽数available len(tasks) - max_count # 可填充的任务数idles max(0, empty_slots - available) # 需要的空闲时间片return len(tasks) idlesprint(任务调度最少时间:, least_interval([A,A,A,B,B,B], 2)) # 8
http://www.gsyq.cn/news/1412807.html

相关文章:

  • 从零到报表:手把手教你用JimuReport对接SpringBoot API(学生信息表实战)
  • WechatDecrypt:3步解密微信聊天记录数据库的完整技术方案
  • 3步解锁你的音乐自由:ncmdumpGUI让网易云NCM文件随处播放
  • ADS1115避坑指南:你的I2C时序对了吗?从逻辑分析仪波形解读到程序调试
  • 从社交网络到商品推荐:超图学习如何帮你发现那些‘意想不到’的关联?一个产品经理的解读
  • Navicat Mac版无限试用重置:3种高效方案彻底破解14天限制
  • 从出租车轨迹到地铁客流:一文读懂如何用图神经网络搞定城市多场景交通预测
  • 树脂瓦寿命选购指南:如何选到长寿命耐用树脂瓦 - 资讯速览
  • 我的第一个Markdown笔记
  • 滑动窗口高频面试题|最长无重复子串、最小子数组
  • 构建上下文感知的本地语音助手:轻量级架构与开源技术栈实践
  • Python自动化LinkedIn求职申请:智能表单填充与反检测实战
  • 感知器算法入门避坑指南:线性可分、收敛性与sklearn的Perceptron使用详解
  • Windows 11网络优先级乱套了?用PowerShell的Set-NetIPInterface命令一键搞定
  • 【独家首发】ChatGPT竞品性能雷达图(覆盖19个维度):我们用217小时压力测试揭开了行业不愿公开的5大真相
  • informix 14 LVM模式安装
  • 别再只复现漏洞了!从ShowDoc文件上传漏洞(CNVD-2020-26585)看企业文档系统的安全加固
  • 怎样专业配置BetterNCM-Installer:5个高效部署网易云插件管理器的实用策略
  • 零基础设施构建个人专属AI代理环境:基于GitHub Codespaces的实战方案
  • 乐山黄金回收实地探访:五大环节实测评分,福昌夏脱颖而出 - 黄金上门回收
  • XUnity.AutoTranslator终极指南:三步实现Unity游戏自动翻译
  • 智能识别之中草药分类识别数据集 中草药分类数据集 47 个草本植物类别 草本植物识别 图像分类数据集10196期
  • 基于随机森林与XGBoost的工业设备预测性健康管理实战
  • 揭秘Hy-MT1.5-1.8B-2bit核心技术:2位量化如何实现极致压缩
  • VMFS队列深度默认值是多少?HBA优化配置完整教程
  • FaceFusion 4.7 整合包来袭!彻底解决换脸跳帧,VisoMaster 2.0 实时速度翻倍(附解压即用教程)
  • 抖音无水印下载工具:3步轻松获取高清视频的完整指南
  • 我的 VSCode 自定义主题
  • 开发创业项目用户增长冷启动方案生成程序,为新项目设计零成本冷启动引流创新方法。
  • CANN/cannbot-skills CUDA迁移规则模式