【python cookbook】【数据结构与算法】5.实现优先级队列

问题:要实现一个队列,它能够以给定的优先级对元素排序,且每次pop操作时都会返回优先级最高的那个元素;

解决方案:采用heapq模块实现一个简单的优先级队列

# example.py
#
# Example of a priority queue

import heapq

class PriorityQueue:
    def __init__(self):
        self._queue = []
        self._index = 0

    def push(self, item, priority):
        heapq.heappush(self._queue, (-priority, self._index, item))
        self._index += 1

    def pop(self):
        return heapq.heappop(self._queue)[-1]

# Example use
class Item:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return ‘Item({!r})‘.format(self.name)

q = PriorityQueue()
q.push(Item(‘foo‘), 1)
q.push(Item(‘bar‘), 5)
q.push(Item(‘spam‘), 4)
q.push(Item(‘grok‘), 1)

print("Should be bar:", q.pop())
print("Should be spam:", q.pop())
print("Should be foo:", q.pop())
print("Should be grok:", q.pop())
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:24:06) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Should be bar: Item(‘bar‘)
Should be spam: Item(‘spam‘)
Should be foo: Item(‘foo‘)
Should be grok: Item(‘grok‘)
>>> 

可以看出:第一次执行pop()操作时返回的元素具有最高的优先级;对于相同优先级的两个元素(foo和gork)返回的顺序同它们插入到队列时的顺序相同。

在这段代码中,队列以元组(-priority, self._index, item)的形式组成,priority取负值是为了队列按照从高到低的顺序排列,这和堆默认的从小到大的排序相反。

变量index的作用是对相同优先级的元素以适当的顺序排列,特别对同优先级的元素间做比较操作时扮演了重要的角色。

Item实例无法进行次序比较:

a=Item(‘foo‘)
b=Item(‘bar‘)
print(‘a<b: ‘,a<b)
>>>
Traceback (most recent call last):
  File "D:\4autotests\02script\python-cookbook\python-cookbook-master\src\1\5.implementing_a_priority_queue\example.py", line 27, in <module>
    print(‘a<b: ‘,a<b)
TypeError: unorderable types: Item() < Item()
>>> 

如果以元组(priority,  item)的形式来表示元素,只要优先级不同,就可进行比较:

a=(1,Item(‘foo‘))
b=(5,Item(‘bar‘))
c=(1,Item(‘gork‘))
print(‘a<b: ‘,a<b)
print(‘a<c: ‘,a<c)
>>>
a<b:  True
Traceback (most recent call last):
  File "D:\4autotests\02script\python-cookbook\python-cookbook-master\src\1\5.implementing_a_priority_queue\example.py", line 29, in <module>
    print(‘a<c: ‘,a<c)
TypeError: unorderable types: Item() < Item()
>>> 

引入额外的索引值,以(priority, index, item)的方式建立元组,就可以避免相同优先级无法比较的问题,因为没有哪两个元组会有相同的index值;

a=(1,0,Item(‘foo‘))
b=(5,1,Item(‘bar‘))
c=(1,2,Item(‘gork‘))
print(‘a<b: ‘,a<b)
print(‘a<c: ‘,a<c)
>>>
a<b:  True
a<c:  True
>>>

如果想将这个队列用于线程间通信,还需要增加适当的锁和信号机制。

时间: 2024-10-13 18:10:22

【python cookbook】【数据结构与算法】5.实现优先级队列的相关文章

普林斯顿公开课 算法4-1:优先级队列API和基本实现

优先级队列是容器的一种,可以向优先级队列中添加或取出数据,取出数据时只能取出最大的数或最小的数.而其他的一些容器比如队列和栈,取出的顺序跟插入的顺序是有关的. 优先级队列的接口如下: public class MaxPQ<Key extends Comparable<Key>> { MaxPQ(); void insert(Key x); Key popMax(); boolean isEmpty(); } 优先级队列的应用 事件驱动的模拟 数字运算 数据压缩 图的查找 数论 人工

Java数据结构和算法之栈与队列

二.栈与队列 1.栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底(Bottom). (2)当表中没有元素时称为空栈. (3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表. 栈的修改是按后进先出的原则进行. 每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除. 图1 [示例]元素是以a1,a2,-,a

普林斯顿公开课 算法4-4:优先级队列的应用

问题 模拟N个运动的小球,小球之间可以发生弹性碰撞 建模 硬碟模型 N个运动的质点,它们之间能发生弹性碰撞,也可以和墙壁发生弹性碰撞 每个质点有明确的位置.速度.质量.半径 没有其他外力 模型应用范围 麦克斯韦:物体的温度和微粒速度分布的关系 爱因斯坦:解释花粉的布朗运动 基本思想 基本思想就是预测小球的碰撞时间,然后将碰撞时间作为优先级队列的关键字进行排序,每次从优先级队列中取出最小的元素,进行碰撞计算,然后重新预测碰撞时间. 这里面涉及到很多物理知识,代码就不演示了. 普林斯顿公开课 算法4

《数据结构与算法》-3-栈和队列

目录 1. 栈 1.1 栈的基本概念 1.2 栈的顺序存储结构 1.3 栈的链式存储结构 2. 队列 2.1 队列的基本概念 2.2 队列的顺序存储结构 2.3 队列的链式存储结构 2.4 双端队列 3. 栈和队列的应用 3.1 栈在括号匹配中的应用 3.2 栈在表达式求值中的应用 3.3 栈对递归中的应用 3.4 队列在层次遍历中的应用 3.5 队列在计算机系统中的应用 4. 特殊矩阵的压缩存储 4.1 数组的定义 4.2 数组的存储结构 4.3 矩阵的压缩存储 ? 该系列博客的目的是为了学习

[0x01 用Python讲解数据结构与算法] 关于数据结构和算法还有编程

忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处. ——奥维德 一.学习目标 · 回顾在计算机科学.编程和问题解决过程中的基本知识: · 理解“抽象”在问题解决过程中的重要作用: · 理解并实现抽象数据结构: · 复习Python编程语言 二.写在前面 自第一台电子计算机使用线路和开关传达人类的指令以来,我们编程的思考方式有了很大的改变,在很多方面,计算机技术的发展为计算机科学家提供了众多的工具和平台去实现他们的想法.高性能理器,高速网络和大内存使得计算机研究者必须掌握在这样复杂的螺旋式通道中

数据结构与算法系列七(队列)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

数据结构与算法(3)-----&gt;队列和栈

1. 栈和队列的基本性质 栈是先进后出;(像是子弹夹,后进先打出) 队列是先进先出;(像是平时排队买冰淇淋,按顺序轮流) 栈和队列在实现的结构上可以有数组和链表两种形式; (1)数组结构实现容易; (2)用链表结构较为复杂,因为牵扯很多的指针操作; 1.1  栈结构的基本操作 (1)pop操作;(弹出) (2)top或peek操作; (3)push操作;(压栈) (4)size操作; 1.2  队列的基本操作 (1)队列的基本操作与栈操作不同的是,push操作作为在队头加入元素;而pop操作是从

Python实现数据结构和算法之桶排序

桶排序 桶排序从 1956 年就开始被使用,该算法的基本思想是由E.J.Issac 和 R.C.Singleton 提出来的. 这个算法就好比有 11 个桶,编号从 0~10.每出现一个数,就在对应编号的桶中放一个小旗子,最后只要数数每个桶中有几个小旗子就 OK 了.例如 2 号桶中有 1 个小旗子,表示2 出现了一次;3 号桶中有 1 个小旗子,表示 3 出现了一次;5 号桶中有 2 个小旗子,表示 5出现了两次;8 号桶中有 1 个小旗子,表示 8 出现了一次. 代码 1 def main(

Python实现数据结构和算法之冒泡排序

冒泡排序 冒泡排序的基本思想是:每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来. 如果有 n 个数进行排序,只需将 n?1 个数归位,也就是说要进行n-1 趟操作.而“每一趟”都需要从第 1 位开始进行相邻两个数的比较,将较小的一个数放在后面,比较完毕后向后挪一位继续比较下面两个相邻数的大小,重复此步骤,直到最后一个尚未归位的数,已经归位的数则无需再进行比较. 代码 1 def _bubbleSort(): 2 a = [] 3 n = int(input('您需要输入几个数进行排序

用JS描述的数据结构及算法表示——栈和队列(基础版)

前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里隐隐歌颂大神的厉害,然后别人的厉害不是我的,所以到底看得各种受打击+头昏脑涨,写这个系列是希望自己能够总结学到东一块.西一下的知识,因为水平有限+经验不足,所以在此只说最基础的思想,附上我自己的算法实现(肯定还有更优解),如果要想看进阶版的,可以在园里搜“数据结构”,各种语言实现和进阶提升的文章有很