Python 内置优先队列PriorityQueue 代码解析
优先队列的出队
大家还记得出队列的方法不?
如下图所示,这个是队列父类queue.Queue类的get方法(取出队列的元素)。
在get方法中调用了优先队列的_get方法(因为被子类PriorityQueue覆盖了)
下面是优先队列的出队操作调用的方法_get
def _get(self):return heappop(self.queue)
复制代码
这里又是用到了二叉堆,我们继续看它的实现:
def heappop(heap):lastelt = heap.pop() if heap:returnitem = heap[0]heap[0] = lastelt_siftup(heap, 0)return returnitemreturn lastelt
复制代码
方法内:
第一行:直接从列表弹出元素(取出)。当整个优先队列取完了,这里遇到空的列表,程序马上报错。(读者可以单独生成一个list对象,直接pop。也就是’[].pop()’)
第二行:继续检测列表heap(维护一个二叉堆结构)是否为空了,如果是,直接运行最后一行(返回列表最后一个元素),并且if内的语句不被执行。 这种情况表示当前列表内仅有最后一个元素,这种最简单了。
否则(第三行开始),需要动态平衡二叉树,进行执行判断。这里主要分为两步:
第一步,也就是我们直接把二叉树顶部节点去掉了,最小堆顶部元素优先数值最小,优先级别最高,直接取就对的。
第二步,把顶部元素换成最后一个加入的元素,直接衔接剩下两颗子树。但此时的二叉树不是最小二叉堆,所以这里就进入了下面的方法。
为了方便解析,直接贴_siftup源码到这,读者可以快速读一下:
def _siftup(heap, pos):endpos = len(heap)startpos = posnewitem = heap[pos]childpos = 2*pos + 1 # leftmost child positionwhile childpos < endpos:rightpos = childpos + 1if rightpos < endpos and not heap[childpos] < heap[rightpos]:childpos = rightposheap[pos] = heap[childpos]pos = childposchildpos = 2*pos + 1heap[pos] = newitem_siftdown(heap, startpos, pos)
复制代码
方法内前三行先确定次起始位置,上层左边元素位置(childpos),顶部元素newitem。
进入循环,这里的退出条件是左边孩子节点位置是否=>剩下列表的长度。因为每次放入元素总是从左到右依次每层放置完。
我们看看循环内部,二叉树左边节点为2pos+1,右边节点为(2pos+1)+1。
通过这行代码‘rightpos < endpos and not heap[childpos] < heap[rightpos]’ ,可以保证在边界内始终:
顶部新节点与左右节点中最小的元素进行位置置换(heap[pos] = heap[childpos]) , 也就是上移左右节点中较小值上升为节点根部,保证后续子树满足最小二叉堆条件。
直到没有后续叶子节点比对。。这时候相当于把一侧最小值获取到,放到顶部执行_siftdown方法,这个在前篇文章解析过了。
总结
优先队列,使用了最小二叉堆为核心,实现了高效出队列和入队列。
稍后在出图展示吧,这里说的高效,主要是优先队列运用二叉树结构来处理出入队,每次不需要整个列表遍历(具体的运算效率下篇展示)。
最后
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑
如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !
PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com
Python 内置优先队列PriorityQueue 代码解析相关推荐
- Python培训分享:Python内置标准异常及其解析
本期小编为大家带来的Python培训教程是关于"Python内置标准异常及其解析"的内容,我们都知道,在Python技术运作下,总会出现一些Python无法正常处理的程序时就会发生 ...
- Python内置函数作用及解析
Python内置的函数及其用法.为了方便记忆,已经有很多开发者将这些内置函数进行了如下分类: 数学运算(7个) 类型转换(24个) 序列操作(8个) 对象操作(7个) 反射操作(8个) 变量操作(2个 ...
- python中f点flush是什么函数_Python文件操作及内置函数flush原理解析
1.打开文件得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 示例文件 '你好呀' 我是于超 嗯 再见 文件操作基本流程 f=open('chenli',encoding='ut ...
- Python内置函数filter()和匿名函数lambda解析
一.内置函数filter filter()函数是 Python 内置的一个高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回由符合条件迭代器 ...
- 用python内置函数算复杂度吗_Python减少代码量的两个内置函数
Python减少代码量的两个内置函数 前言 Python中内置了几个非常好用的函数. 当你掌握了这几个函数的用法后,有些场景下,不用自己去实现多余的冗余代码编写,只需要调用这些函数,便能很简短的帮你实 ...
- 使用python内置2to3工具将python2代码转换为python3代码
我们都知道python有一个一直被诟病的毛病,python2与python3代码不兼容问题,而网上的一些教学大部分都是python2的,如果需要将其在python3环境下运行,有两个方法,一是:一个一 ...
- python抢券代码_京东python抢券脚本Python内置函数——str
www.002pc.com对<京东python抢券脚本Python内置函数--str>总结来说,为我们学习Python很实用. str[code]str([object]) 转换为stri ...
- 剑指 Offer 面试题45:把数组排成最小的数——Python内置函数 map()、__lt__()、join()、sorted()
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个. 输出结果可能非常大,所以需要返回一个字符串而不是整数. 拼接起来的数字可能会有前导 0,最后结果 ...
- 【Python】Python3.7.3 - Python内置函数
文章目录 系统参数 Python内置函数 abs() all() any() ascii() repr() eval() 空值为假,非空为真 系统参数 [tony@tony-controller bi ...
最新文章
- java反射的性能_java反射的性能问题
- 历届华人 AAAI Fellows
- 1.1 Friday the Thirteenth
- python批量下载网页文件-Python实现批量下载文件
- 2021-10-20 哈希表 恋上数据结构笔记
- 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)
- 最短路 + 搜索 + 剪枝 之 hdu 4848 Wow! Such Conquering!
- 未从创建控件的线程访问解决办法
- 网络通信之通过get/post方式提交参数给web应用
- PHP PDF转图片:设置图像的色彩空间 RGBCMYK互转
- 阿里云的yum源配置
- Polarion软件下载安装使用试用
- 2020 ECCV 所有论文及补充材料链接(二)
- 地理科学与计算机技术的关系,地理信息系统与地理学的关系
- Windows无法访问网络共享解决办法
- 【计算几何】计算几何复习
- (15)卡巴斯基防病毒软件介绍-概述
- 翻转棋c语言算法,有没有人懂黑白棋(翻转棋)的核心算法
- odoo12 数据文件翻译
- CCF CSP认证考试在线评测系统