分享一个小技巧

99 阅读3分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」。

正式的Python专栏第64篇,同学站住,别错过这个从0开始的文章! 前面学委说要把内置队列都撸一撸,前面展示了有简单的先进后出,先进先出队列。

今天把优先队列先展示了。

PriorityQueue

这是一个懂得分辨轻重缓急的队列。 之前FIFO/FILO这些都是按照放入顺序,先放进去的要么先出队,要么后面出队。

实际应用场景跟我们日常类似,比如我们去一个高级餐厅吃饭。 通常他们会设置会员等级,比如常客VIP,或者那种高级VIP(VVIP),这些入队。 前台服务人员就会根据客户登记安排客户进场。 这时候优先队列就派上用场。

优先队列可以放入元素格式如下:

q = PriorityQueue()

二元组(优先级数,数据 )

q.put((3, '小白')) 下面是模拟整个队列排队:

#!/usr/bin/env python

-- coding: utf-8 --

@Time : 2022/2/14 11:13 下午

@Author : LeiXueWei

@CSDN/Juejin/Wechat: 雷学委

@XueWeiTag: CodingDemo

@File : priorityqdemo.py

@Project : hello

from queue import PriorityQueue

q = PriorityQueue()

q.put((3, '小白')) #后到 q.put((2, '雷学委')) #最后到 q.put((1, '小花'))

while not q.empty(): next_item = q.get() print("🐰 欢迎 %s 用餐:" % str(next_item)) 首先,小白没有VIP先到拿号了。 然后学委,小花陆续去餐厅排队。

直接运行代码,可以看到小花同学最后到场,但是她缺第一个进去餐厅内堂用餐了。

没办法,她是VVIP,级别最高(第三个元素的数值最小)所以放到最前面了。

效果图如下:

屏幕快照 2022-02-14 下午11.47.28.png

所以就很‘合理’(没办法,谁叫你去高级餐厅排队,去个普通的餐厅,我们就用普通FIFO队列来管理用餐秩序了)。

优先队列怎么排队的?

打开queue这个库直接看到PriorityQueue这个类源码:

屏幕快照 2022-02-14 下午11.52.11.png

太简单了,直接继承了Queue父类。

不过我们看到优先队列覆盖了_put方法,用了heappush方法来放元素到二叉堆(这个是在heapq内置库里面的一个方法,也有取元素的实现)。

def heappush(heap, item): """Push item onto heap, maintaining the heap invariant.""" heap.append(item) _siftdown(heap, 0, len(heap)-1)

headpush内部直接把新入队的元素放到队尾(前面heap=[])

然后执行下面的方法摆放元素:

def _siftdown(heap, startpos, pos): newitem = heap[pos] # Follow the path to the root, moving parents down until finding a place # newitem fits. while pos > startpos: parentpos = (pos - 1) >> 1 parent = heap[parentpos] if newitem < parent: heap[pos] = parent pos = parentpos continue break heap[pos] = newitem 这里使用[最小二叉堆(baike.baidu.com/item/%E6%9C…) ,通过不断与父节点对比(父节点的位置为parentpos = (pos - 1) >> 1)。

循环比对,如果新加元素小于父节点,当前新加节点上移(也就是父节点下移到新节点每次放入的新位置)

直到找到一个父节点是小于新节点值的位置,停止移动,入队操作完毕。

这一段比较烧脑,先解释这个入队。后面再做一个图形展示一下。

总结

优先队列,就像高级餐厅或者银行排队VIP/VVIP这种,特殊人群特殊安排。

内部实现用了二叉树这个数据结构,后面学委再做图展示。

前篇学委说了这个, 再次放在一起,比对回顾:

后进先出队列,很像超市货柜,后面放的物品,先被消费者看到。 先进先出队列,就像大家排队体检,排队打饭一样。肯定是先到的先安排。 优先队列,就像高级餐厅或者银行排队VIP/VVIP这种,特殊人群特殊安排。 喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏

持续学习持续开发,我是雷学委! 编程很有趣,关键是把技术搞透彻讲明白。 欢迎关注微信,点赞支持收藏!