优先队列的出队
大家还记得出队列的方法不?

如下图所示,这个是队列父类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 代码解析相关推荐

  1. Python培训分享:Python内置标准异常及其解析

    本期小编为大家带来的Python培训教程是关于"Python内置标准异常及其解析"的内容,我们都知道,在Python技术运作下,总会出现一些Python无法正常处理的程序时就会发生 ...

  2. Python内置函数作用及解析

    Python内置的函数及其用法.为了方便记忆,已经有很多开发者将这些内置函数进行了如下分类: 数学运算(7个) 类型转换(24个) 序列操作(8个) 对象操作(7个) 反射操作(8个) 变量操作(2个 ...

  3. python中f点flush是什么函数_Python文件操作及内置函数flush原理解析

    1.打开文件得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 示例文件 '你好呀' 我是于超 嗯 再见 文件操作基本流程 f=open('chenli',encoding='ut ...

  4. Python内置函数filter()和匿名函数lambda解析

    一.内置函数filter filter()函数是 Python 内置的一个高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回由符合条件迭代器 ...

  5. 用python内置函数算复杂度吗_Python减少代码量的两个内置函数

    Python减少代码量的两个内置函数 前言 Python中内置了几个非常好用的函数. 当你掌握了这几个函数的用法后,有些场景下,不用自己去实现多余的冗余代码编写,只需要调用这些函数,便能很简短的帮你实 ...

  6. 使用python内置2to3工具将python2代码转换为python3代码

    我们都知道python有一个一直被诟病的毛病,python2与python3代码不兼容问题,而网上的一些教学大部分都是python2的,如果需要将其在python3环境下运行,有两个方法,一是:一个一 ...

  7. python抢券代码_京东python抢券脚本Python内置函数——str

    www.002pc.com对<京东python抢券脚本Python内置函数--str>总结来说,为我们学习Python很实用. str[code]str([object]) 转换为stri ...

  8. 剑指 Offer 面试题45:把数组排成最小的数——Python内置函数 map()、__lt__()、join()、sorted()

    题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个. 输出结果可能非常大,所以需要返回一个字符串而不是整数. 拼接起来的数字可能会有前导 0,最后结果 ...

  9. 【Python】Python3.7.3 - Python内置函数

    文章目录 系统参数 Python内置函数 abs() all() any() ascii() repr() eval() 空值为假,非空为真 系统参数 [tony@tony-controller bi ...

最新文章

  1. java反射的性能_java反射的性能问题
  2. 历届华人 AAAI Fellows
  3. 1.1 Friday the Thirteenth
  4. python批量下载网页文件-Python实现批量下载文件
  5. 2021-10-20 哈希表 恋上数据结构笔记
  6. 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)
  7. 最短路 + 搜索 + 剪枝 之 hdu 4848 Wow! Such Conquering!
  8. 未从创建控件的线程访问解决办法
  9. 网络通信之通过get/post方式提交参数给web应用
  10. PHP PDF转图片:设置图像的色彩空间 RGBCMYK互转
  11. 阿里云的yum源配置
  12. Polarion软件下载安装使用试用
  13. 2020 ECCV 所有论文及补充材料链接(二)
  14. 地理科学与计算机技术的关系,地理信息系统与地理学的关系
  15. Windows无法访问网络共享解决办法
  16. 【计算几何】计算几何复习
  17. (15)卡巴斯基防病毒软件介绍-概述
  18. 翻转棋c语言算法,有没有人懂黑白棋(翻转棋)的核心算法
  19. odoo12 数据文件翻译
  20. CCF CSP认证考试在线评测系统

热门文章

  1. js实现导航栏随着页面向下滑动逐渐显示,向上滑动逐渐隐藏
  2. 易语言暗色系UI源码分享
  3. 编程任务编号 O: 五人列队
  4. php闭包是什么意思_php闭包是什么
  5. esdump离线安装
  6. java雪花纷飞_下雪了 javascript实现雪花飞舞
  7. 索尼、联想新款笔记本物有所值
  8. QQ空间日志抓器---我的第一个winform小应用(多线程,附源码)
  9. 【Vim】IdeaVim高级玩法之EasyMotion插件
  10. 看到别人用Python自动化运维实现的神办公,我开始慌了!