demo1

实现一个按优先级排序的队列, 并且在这个队列上面每次 pop 操作总是返回优先级最高的那个元素

import heapq
class PriorityQueue:
def __init__(self):
self._queue = []
self._index = def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += def pop(self):
return heapq.heappop(self._queue)[-] x=PriorityQueue()
x.push(,)
print(x.pop())

输出:


使用:

>>> class Item:
... def __init__(self, name):
... self.name = name
... def __repr__(self):
... return 'Item({!r})'.format(self.name)
...
>>> q = PriorityQueue()
>>> q.push(Item('foo'), )
>>> q.push(Item('bar'), )
>>> q.push(Item('spam'), )
>>> q.push(Item('grok'), )
>>> q.pop()
Item('bar')
>>> q.pop()
Item('spam')
>>> q.pop()
Item('foo')
>>> q.pop()
Item('grok')
>>>

仔细观察可以发现,第一个 pop() 操作返回优先级最高的元素。 另外注意到如果两个有着相同优先级的元素( foo 和 grok ),pop 操作按照它们被插入到队列的顺序返回的.

函数 heapq.heappush() 和 heapq.heappop() 分别在队列 _queue 上插入和删除第一个元素, 并且队列 _queue 保证第一个元素拥有最高优先级( 1.4 节已经讨论过这个问题)。 heappop() 函数总是返回”最小的”的元素,这就是保证队列pop操作返回正确元素的关键。 另外,由于 push 和 pop 操作时间复杂度为 O(log N),其中 N 是堆的大小,因此就算是 N 很大的时候它们运行速度也依旧很快。

在上面代码中,队列包含了一个 (-priority, index, item) 的元组。 优先级为负数的目的是使得元素按照优先级从高到低排序。 这个跟普通的按优先级从低到高排序的堆排序恰巧相反。

index 变量的作用是保证同等优先级元素的正确排序。 通过保存一个不断增加的 index 下标变量,可以确保元素按照它们插入的顺序排序。 而且, index 变量也在相同优先级元素比较的时候起到重要作用。

为了阐明这些,先假定 Item 实例是不支持排序的:

>>> a = Item('foo')
>>> b = Item('bar')
>>> a < b
Traceback (most recent call last):
File "<stdin>", line , in <module>
TypeError: unorderable types: Item() < Item()
>>>

如果你使用元组 (priority, item) ,只要两个元素的优先级不同就能比较。 但是如果两个元素优先级一样的话,那么比较操作就会跟之前一样出错:

>>> a = (, Item('foo'))
>>> b = (, Item('bar'))
>>> a < b
True
>>> c = (, Item('grok'))
>>> a < c
Traceback (most recent call last):
File "<stdin>", line , in <module>
TypeError: unorderable types: Item() < Item()
>>>

通过引入另外的 index 变量组成三元组 (priority, index, item) ,就能很好的避免上面的错误, 因为不可能有两个元素有相同的 index 值。Python 在做元组比较时候,如果前面的比较已经可以确定结果了, 后面的比较操作就不会发生了:

class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Item({!r})'.format(self.name) a = (, , Item('foo'))
b = (, , Item('bar'))
c = (, , Item('grok'))
print(a>b)
print(a<c)

输出

False
True

实现一个优先级队列,每次pop 返回优先级最高的元素的更多相关文章

  1. d-ary heap实现一个快速的优先级队列(C#)

    d-ary heap简介: d-ary heap 是泛化版本的binary heap(d=2),d-ary heap每个非叶子节点最多有d个孩子结点. d-ary heap拥有如下属性: 类似comp ...

  2. 用NodeJs实现优先级队列PQueue

    优先级队列(PriorityQueue)是个很有用的数据结构,很多编程语言都有实现.NodeJs是一个比较新潮的服务器语言,貌似还没有提供相关类.这些天有用到优先级队列,因为时间很充足,闲来无事,就自 ...

  3. 自己动手实现java数据结构(八) 优先级队列

    1.优先级队列介绍 1.1 优先级队列 有时在调度任务时,我们会想要先处理优先级更高的任务.例如,对于同一个柜台,在决定队列中下一个服务的用户时,总是倾向于优先服务VIP用户,而让普通用户等待,即使普 ...

  4. GO语言heap剖析及利用heap实现优先级队列

    GO语言heap剖析 本节内容 heap使用 heap提供的方法 heap源码剖析 利用heap实现优先级队列 1. heap使用 在go语言的标准库container中,实现了三中数据类型:heap ...

  5. 实现优先级队列 --heapq模块

    以给定的优先级对元素进行排序,每次pop删除优先级最高的 # coding=utf-8 # example.py # # Example of a priority queue import heap ...

  6. 【优先级队列】Southwestern Europe Regional Contest Canvas Painting

    https://vjudge.net/contest/174235#problem/D [题意] 给定n个已知size的帆布,要给这n块帆布涂上不同的颜色,规则是这样的: 每次选择一种颜色C 对于颜色 ...

  7. STL之优先级队列priority_queue

    摘要: priority_queue,自适应容器(即容器适配器):不能由list来组建: 最大值优先级队列(最大值始终在对首,push进去时候) 最小值优先级队列: 优先级队列适配器 STL  pri ...

  8. C++STL模板库适配器之优先级队列

    目录 适配器之优先级队列 一丶优先级队列简介(priority_queue) 二丶优先级队列代码演示 1.优先级队列代码以及使用简介 适配器之优先级队列 一丶优先级队列简介(priority_queu ...

  9. RabbitMQ 优先级队列-为队列赋权

    RabbitMQ 消息收发是按顺序收发,一般情况下是先收到的消息先处理,即可以实现先进先出的消息处理.但如果消息者宕机或其他原因,导致消息接收以后,未确认,那么消息会重新Requeue到队列中,就打破 ...

随机推荐

  1. Python基础二_操作字符串常用方法、字典、文件读取

    一.字符串常用方法: name.captitalize()                       #字符串首字母大写 name.center(50,'*')                   ...

  2. django框架基本介绍

    一.mvc和mtv 1.mvc介绍 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器( ...

  3. Mysql初级第二天(wangyun)

    SQL 1.LIKE 操作符 SELECT 列名称 FROM 表名称 WHERE 列 LIKE 值('N%'/'%N%'/'%N','N_') SELECT 列名称 FROM 表名称 WHERE 列 ...

  4. Q_DECL_OVERRIDE

    Q_DECL_OVERRIDE也就是c++的override # define Q_DECL_OVERRIDE override 在重写虚函数时会用到, 作用是防止写错虚函数: void keyPre ...

  5. 论文翻译——Rapid 2D-to-3D conversion——快速2D到3D转换

    https://blog.csdn.net/qq_33445835/article/details/80143598  目前想做一个关于2D转3D的项目,由于国内资料比较少而且大部分都是基于国外的研究 ...

  6. Golang获取int数组里的最大值和下标

    package main import ( "fmt" ) func main() { //获取一个数组里最大值,并且拿到下标 //声明一个数组5个元素 ], , , ,} //假 ...

  7. Spring Boot(十七):使用Spring Boot上传文件

    Spring Boot(十七):使用Spring Boot上传文件 环境:Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0 一.pom包配置 <parent> ...

  8. jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解

    jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如 ...

  9. 02: git分支管理

    目录:GIT其他篇 01: git & github 02: git分支管理 目录: 1.1 Git常用命令 1.2 主要分支(保护分支) 1.3 特性分支:feature (开发分支合并到d ...

  10. ldap集成jenkins

    jenkins版本:2.5.3,ldap插件:1.15 jenkins ldap支持需要安装ldap plugin,强烈建议插件安装版本为1.15及以上(支持ldap 配置测试) 安装插件: 系统管理 ...