python数据结构与算法-16_优先级队列

优先级队列

你可能比较奇怪,队列不是早就讲了嘛。这里之所以放到这里讲优先级队列,是因为虽然名字有队列,
但其实是使用堆来实现的。上一章讲完了堆,这一章我们就趁热打铁来实现一个优先级队列。

实现优先级队列

优先级队列(Priority Queue) 顾名思义,就是入队的时候可以给一个优先级,通常是个数字或者时间戳等,
当出队的时候我们希望按照给定的优先级出队,我们按照 TDD(测试驱动开发) 的方式先来写测试代码:

def test_priority_queue():size = 5pq = PriorityQueue(size)pq.push(5, 'purple')    # priority, valuepq.push(0, 'white')pq.push(3, 'orange')pq.push(1, 'black')res = []while not pq.is_empty():res.append(pq.pop())assert res == ['purple', 'orange', 'black', 'white']

上边就是期望的行为,写完测试代码后我们来编写优先级队列的代码,按照出队的时候最大优先级先出的顺序:

class PriorityQueue(object):def __init__(self, maxsize):self.maxsize = maxsizeself._maxheap = MaxHeap(maxsize)def push(self, priority, value):# 注意这里把这个 tuple push 进去,python 比较 tuple 从第一个开始比较# 这样就很巧妙地实现了按照优先级排序entry = (priority, value)    # 入队的时候会根据 priority 维持堆的特性self._maxheap.add(entry)def pop(self, with_priority=False):entry = self._maxheap.extract()if with_priority:return entryelse:return entry[1]def is_empty(self):return len(self._maxheap) == 0

源码

# -*- coding:utf-8 -*-# 第二章拷贝的 Array 代码class Array(object):def __init__(self, size=32):self._size = sizeself._items = [None] * sizedef __getitem__(self, index):return self._items[index]def __setitem__(self, index, value):self._items[index] = valuedef __len__(self):return self._sizedef clear(self, value=None):for i in range(len(self._items)):self._items[i] = valuedef __iter__(self):for item in self._items:yield item#####################################################
# heap 实现
#####################################################class MaxHeap(object):"""Heaps:完全二叉树,最大堆的非叶子节点的值都比孩子大,最小堆的非叶子结点的值都比孩子小Heap包含两个属性,order property 和 shape property(a complete binary tree),在插入一个新节点的时候,始终要保持这两个属性插入操作:保持堆属性和完全二叉树属性, sift-up 操作维持堆属性extract操作:只获取根节点数据,并把树最底层最右节点copy到根节点后,sift-down操作维持堆属性用数组实现heap,从根节点开始,从上往下从左到右给每个节点编号,则根据完全二叉树的性质,给定一个节点i, 其父亲和孩子节点的编号分别是:parent = (i-1) // 2left = 2 * i + 1rgiht = 2 * i + 2使用数组实现堆一方面效率更高,节省树节点的内存占用,一方面还可以避免复杂的指针操作,减少调试难度。"""def __init__(self, maxsize=None):self.maxsize = maxsizeself._elements = Array(maxsize)self._count = 0def __len__(self):return self._countdef add(self, value):if self._count >= self.maxsize:raise Exception('full')self._elements[self._count] = valueself._count += 1self._siftup(self._count-1)  # 维持堆的特性def _siftup(self, ndx):if ndx > 0:parent = int((ndx-1)/2)if self._elements[ndx] > self._elements[parent]:    # 如果插入的值大于 parent,一直交换self._elements[ndx], self._elements[parent] = self._elements[parent], self._elements[ndx]self._siftup(parent)    # 递归def extract(self):if self._count <= 0:raise Exception('empty')value = self._elements[0]    # 保存 root 值self._count -= 1self._elements[0] = self._elements[self._count]    # 最右下的节点放到root后siftDownself._siftdown(0)    # 维持堆特性return valuedef _siftdown(self, ndx):left = 2 * ndx + 1right = 2 * ndx + 2# determine which node contains the larger valuelargest = ndxif (left < self._count and     # 有左孩子self._elements[left] >= self._elements[largest] andself._elements[left] >= self._elements[right]):  # 原书这个地方没写实际上找的未必是largestlargest = leftelif right < self._count and self._elements[right] >= self._elements[largest]:largest = rightif largest != ndx:self._elements[ndx], self._elements[largest] = self._elements[largest], self._elements[ndx]self._siftdown(largest)class PriorityQueue(object):def __init__(self, maxsize):self.maxsize = maxsizeself._maxheap = MaxHeap(maxsize)def push(self, priority, value):entry = (priority, value)    # 注意这里把这个 tuple push进去,python 比较 tuple 从第一个开始比较self._maxheap.add(entry)def pop(self, with_priority=False):entry = self._maxheap.extract()if with_priority:return entryelse:return entry[1]def is_empty(self):return len(self._maxheap) == 0def test_priority_queue():size = 5pq = PriorityQueue(size)pq.push(5, 'purple')pq.push(0, 'white')pq.push(3, 'orange')pq.push(1, 'black')res = []while not pq.is_empty():res.append(pq.pop())assert res == ['purple', 'orange', 'black', 'white']def test_buildin_PriorityQueue():  # python3"""测试内置的 PriorityQueuehttps://pythonguides.com/priority-queue-in-python/"""from queue import PriorityQueueq = PriorityQueue()q.put((10, 'Red balls'))q.put((8, 'Pink balls'))q.put((5, 'White balls'))q.put((4, 'Green balls'))while not q.empty():item = q.get()print(item)def test_buildin_heapq_as_PriorityQueue():"""测试使用 heapq 实现优先级队列,保存一个 tuple 比较元素(tuple第一个元素是优先级)"""import heapqs_roll = []heapq.heappush(s_roll, (4, "Tom"))heapq.heappush(s_roll, (1, "Aruhi"))heapq.heappush(s_roll, (3, "Dyson"))heapq.heappush(s_roll, (2, "Bob"))while s_roll:deque_r = heapq.heappop(s_roll)print(deque_r)# python3 没有了 __cmp__ 魔法函数 https://stackoverflow.com/questions/8276983/why-cant-i-use-the-method-cmp-in-python-3-as-for-python-2
class Item:def __init__(self, key, weight):self.key, self.weight = key, weightdef __lt__(self, other): # 看其来 heapq 实现只用了 小于 比较,这里定义了就可以 push 一个 item 类return self.weight < other.weightdef __eq__(self, other):return self.weight == other.weightdef __str__(self):return '{}:{}'.format(self.key,self.weight)def test_heap_item():"""测试使用 Item 类实现优先级队列,因为 heapq 内置使用的是小于运算法,重写魔术 < 比较方法即可实现"""import heapqpq = []heapq.heappush(pq, Item('c', 3))heapq.heappush(pq, Item('a', 1))heapq.heappush(pq, Item('b', 2))while pq:print(heapq.heappop(pq))

练习题

  • 请你实现按照小优先级先出队的顺序的优先级队列

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

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

相关文章

UWA报告使用技巧小视频,你get了么?(第十一弹)

随着玩家对手游渲染品质的要求日益趋上&#xff0c;60帧、各种花式后处理导致发热、耗电等问题日趋明显。本期UWA报告使用技巧将分享关于GPU优化的专题姊妹篇。 《GPU性能优化篇》 UWA专注于手游GPU性能的优化&#xff0c;以确保您的游戏体验得以最佳展现。基于最新发布的GOT …

141.【Git版本控制】

Git-深入挖掘 (一)、Git分布式版本控制工具1.目标2.概述(1).开发中的实际常见(2).版本控制器的方式(3).SVN (集中版本控制器)(4).Git (分布版本控制器)(5).Git工作流程图 (二)、Git安装与常用命令1.Git环境配置(1).安装Git的操作(2).Git的配置操作(3).为常用的指令配置别名 (可…

轻松解决rpm软件包的依赖问题 yum download ,rpm和deb不同系列

centos rpm系列的 为它往往有很多依赖项目。比如&#xff0c;我们来查看一下net-tools的依赖项有哪些&#xff1a; yum deplist net-tools 推荐使用以下几种方法&#xff1a; 1.repotrack 我这里也以上期讲到的Mariadb为例演示&#xff0c;以下操作需要在有网络的环境下进…

国内企业出海首选的免费开源订单管理系统(OMS)解决方案

用开源智造Odoo订单管理系统 (OMS) 解决方案实现"订单到收款"流程自动化 开源智造Odoo 订单管理软件功能消除了手动操作瓶颈&#xff0c;可防止出错&#xff0c;还建立了从销售报价到订单履行的顺畅工作流来确保及时开票和付款&#xff0c;从而帮助您理顺订单处理过程…

Python将多个视频帧组合成.mp4视频

已经有很多文章描述了如何将视频拆分成视频帧&#xff0c;例如&#xff1a;https://blog.csdn.net/WYKB_Mr_Q/article/details/124929081 那我们如何将很多视频帧重新组合成视频呢&#xff1f; 这里我们主要用到了 OpenCV 库中的 VideoWriter 类。 OpenCV种的 cv2.VideoWrit…

jdbc批量插入或更新数据

mybatis可以批量插入或更新数据&#xff0c;不过mybatis底层也是基于jdbc来实现的&#xff0c;如何使用jdbc批量操作数据&#xff1f;本文给出demo。 /*** JDBC分批次批量插入* * throws IOException*/public static void testJDBCBatchInsertUser() throws IOException {Conne…

工作流引擎的架构设计主要考虑以下方面

工作流引擎的架构设计主要考虑以下方面&#xff0c;以驰骋工作流引擎为例来说明。 高度抽象和封装&#xff1a;为了适应各种业务场景&#xff0c;工作流引擎应具备高度抽象和封装的特性&#xff0c;以便统一处理各流程。灵活配置&#xff1a;工作流引擎应支持灵活的配置&#…

Linux之实现简易的shell

1.打印提示符并获取命令行 我们在使用shell的时候&#xff0c;发现我们在输入命令是&#xff0c;前面会有&#xff1a;有用户名&#xff0c;版本&#xff0c;当前路径等信息&#xff0c;这里我们可以用环境变量去获取: 1 #include <stdio.h>2 #include <stdlib.h>…

python如何快速查找到想要的文档

字多不看版&#xff0c;直接体验 待补充 演示代码 # -*- coding:UTF-8 -*-# region 导入必要的依赖包 import os import subprocess from enum import Enum模块名 pyperclip try:import pyperclip # 需要安装 pyperclip 模块&#xff0c;以支持粘贴板操作 except ImportEr…

PTA-成绩转换

本题要求编写程序将一个百分制成绩转换为五分制成绩。转换规则&#xff1a; 大于等于90分为A&#xff1b;小于90且大于等于80为B&#xff1b;小于80且大于等于70为C&#xff1b;小于70且大于等于60为D&#xff1b;小于60为E。 输入格式: 输入在一行中给出一个整数的百分制成…

羊大师教你如何科学控制体重,轻松瘦下来

羊大师教你如何科学控制体重&#xff0c;轻松瘦下来 我们都知道&#xff0c;控制体重对于保持健康和美丽至关重要。然而&#xff0c;许多人在减肥的道路上走得波折重重&#xff0c;常常陷入挫败和不知所措的境地。那么&#xff0c;如何科学控制体重&#xff0c;轻松瘦下来呢&a…

项目经理只需要有PMP证书就行?

就目前而言&#xff0c;大部分人对于项目经理的认识还停留在&#xff1a;有项目管理经验&#xff0c;有对应的工作年限&#xff0c;有PMP证书。所以绝大多数人都认为只要报考了PMP项目管理&#xff0c;取得PMP证书&#xff0c;即可加入项目经理的圈子&#xff0c;薪资翻倍。 但…

协同过滤与矩阵分解讲解(PPT)

总览 协同过滤算法&#xff0c;就是一种完全依赖用户和物品之间行为关系的推荐算法。 从字面理解&#xff0c;协同大家的反馈、评价和意见一起对海量的信息进行过滤&#xff0c;从中筛选出用户可能感兴趣的信息。 知识概括 从这几个方面进行分析。 一、基于用户的协同过滤 显示…

6个PPT素材网站,让你快速做出好看的PPT

找PPT模板一定要收藏好这6个网站&#xff0c;能让你快速做出好看的PPT&#xff0c;重点十可以免费下载&#xff0c;赶紧收藏&#xff01; 1、菜鸟图库 https://www.sucai999.com/search/ppt/0_0_0_1.html?vNTYwNDUx 菜鸟图库网有非常丰富的免费素材&#xff0c;像设计类、办公…

力扣labuladong——一刷day48

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣1602. 找到二叉树中最近的右侧节点二、力扣437. 路径总和 III三、力扣560. 和为 K 的子数组 前言 二叉树的递归分为「遍历」和「分解问题」两种思维模式…

第7章-使用统计方法进行变量有效性测试-7.4.2-多元线性回归

目录 多元线性回归模型 总体回归函数 样本回归函数 线性回归模型的假定 普通最小二乘法&#xff08;Ordinary Least Squares&#xff0c;OLS&#xff09; 拟合优度指标 F检验 回归系数的t检验 Python中构建多元线性回归模型 数据理解 数据读取 数据清洗 相关分析 …

想考教师编制专业不对口怎么办?

很多人在想要步入教师行业时&#xff0c;会遇到一个问题&#xff1a;专业不对口。这种情况可能会让你感到困惑和沮丧&#xff0c;但不要气馁&#xff0c;因为有很多方法可以让你实现自己的梦想。 可以通过提高自己的教育水平和能力来弥补专业不对口的缺陷。你可以通过参加教师资…

品牌小红书koc投放策略分享,纯干货!

作为中国具有影响力的时尚美妆社交平台&#xff0c;小红书与其充满活力的用户群体成为品牌寻找优质KOC合作的理想平台。本文伯乐网络传媒将探讨品牌如何利用小红书的KOC投放策略&#xff0c;实现更广泛的市场覆盖和更有效的品牌营销。 一、明确目标受众与KOC合作需求 在开始策…

containerd Snapshots功能解析

containerd Snapshots功能解析 snapshot是containerd的一个核心功能&#xff0c;用于创建和管理容器的文件系统。 本篇containerd版本为v1.7.9。 本文以 ctr i pull命令为例&#xff0c;分析containerd的snapshot “创建” 相关的功能。 ctr命令 ctr image相关命令的实现在cmd…

《人件》读书笔记

文章目录 一、书名和作者二、书籍概览2.1 主要论点和结构2.2 目标读者和应用场景 三、核心观点与主题3.1 管理团队主题3.2 改善工作环境主题3.3 正确的人主题3.4 团队项目管理主题 四、亮点与启发4.1 最有影响的观点4.2 对个人专业发展的启示 五、批评与局限性5.1 可能存在争议…