python 堆和优先队列的使用详解


Posted in Python onMarch 05, 2019

1.heapq

python里面的堆是通过在列表中维护堆的性质实现的。这一点与C++中heap一系列的算法类似,底层是通过堆vector的维护获取堆的性质。

关于二叉树

二叉树的特点:

二叉树是一种存储数据元素的汇集数据结构。

二叉树最重要的性质就是树的高度和树中可以容纳的最大结点个数之间的关系。树的高度类似于表长,是从根结点到其他结点的最大距离。在长为n的表里只能容纳n个结点,而在高为h的二叉树中则可以容纳大约2^h个结点,这是表和树的最大不同点。

一般的元素插入,如果是按线性顺序排列的,那么操作必然需要O(n)的时间(需要对n个数据进行移位处理),要突破这个限制,必须考虑其他数据结构的组织方式。二叉树就是一种高效插入的存储方式。

堆排序利用的是完全二叉树。

python堆的部分API,其他API查阅文档python_heap_API和  heapq的源代码

import heapq
#向堆中插入元素,heapq会维护列表heap中的元素保持堆的性质
heapq.heappush(heap, item)
#heapq把列表x转换成堆
heapq.heapify(x)
#从可迭代的迭代器中返回最大的n个数,可以指定比较的key
heapq.nlargest(n, iterable[, key])
#从可迭代的迭代器中返回最小的n个数,可以指定比较的key
heapq.nsmallest(n, iterable[, key])
#从堆中删除元素,返回值是堆中最小或者最大的元素
heapq.heappop(heap)

1.1.内置类型

从上述源代码可以看出来,heapq使用的内置的小于号,或者类的__lt__比较运算来进行比较。

def heapq_int():
  heap = []
  #以堆的形式插入堆
  heapq.heappush(heap,10)
  heapq.heappush(heap,1)
  heapq.heappush(heap,10/2)
  [heapq.heappush(heap,i) for i in range(10)]
  [heapq.heappush(heap,10 - i) for i in range(10)]
  #最大的10个元素
  print heapq.nlargest(10,heap)
  #输出所有元素
  print [heapq.heappop(heap) for i in range(len(heap))]

1.2.元组类型

元素会默认调用内置比较函数cmp

def heapq_tuple():
  heap = []
  #向推中插入元组
  heapq.heappush(heap,(10,'ten'))
  heapq.heappush(heap,(1,'one'))
  heapq.heappush(heap,(10/2,'five'))
  while heap:
    print heapq.heappop(heap),
  print

1.2.类类型

类类型,使用的是小于号_lt_,当然没有重写但是有其他的比较函数例如:_le_,_gt_,_cmp_,也是会调用的,和小于号等价的都可以调用(测试了gt),具体的这些操作之间的关系我也没有研究过。如果类里面没有重写_lt_,会调用其他的比较操作符,从源代码可以看出来,如果没有_lt_,那么会调用_ge_函数。

所以可以重写上述的那些函数:

class Skill(object):
  def __init__(self,priority,description):
    self.priority = priority
    self.description = description
  def __lt__(self,other):#operator < 
    return self.priority < other.priority
  def __ge__(self,other):#oprator >=
    return self.priority >= other.priority
  def __le__(self,other):#oprator <=
    return self.priority <= other.priority
  def __cmp__(self,other):
    #call global(builtin) function cmp for int
    return cmp(self.priority,other.priority)
  def __str__(self):
    return '(' + str(self.priority)+',\'' + self.description + '\')'

def heapq_class():
  heap = []
  heapq.heappush(heap,Skill(5,'proficient'))
  heapq.heappush(heap,Skill(10,'expert'))
  heapq.heappush(heap,Skill(1,'novice'))
  while heap:
    print heapq.heappop(heap),
  print

所以如果要用到自己定义的类型,可以重写上述函数,就可以使用heapq函数了。

2.PriorityQueue

PriorityQueue的python源代码PriorityQueue 

从源代码可以看出来,PriorityQueue使用的就是heapq来实现的,所以可以认为两者算法本质上是一样的。当然PriorityQueue考虑到了线程安全的问题。

下面给出PriorityQueue的部分API和使用方法。

参考Queue

#向队列中添加元素
Queue.put(item[, block[, timeout]])
#从队列中获取元素
Queue.get([block[, timeout]])
#队列判空
Queue.empty()
#队列大小
Queue.qsize()

2.1.内置类型

直接调用内置函数cmp进行比较

try:
  import Queue as Q #python version < 3.0
except ImportError:
  import queue as Q #python3.*
def PriorityQueue_int():
  que = Q.PriorityQueue()
  que.put(10)
  que.put(1)
  que.put(5)
  while not que.empty():
    print que.get(),
  print

2.2.元组类型

def PriorityQueue_tuple():
  que = Q.PriorityQueue()
  que.put((10,'ten'))
  que.put((1,'one'))
  que.put((10/2,'five'))
  while not que.empty():
    print que.get(),
  print

2.2.自定义类型

class Skill(object):
  def __init__(self,priority,description):
    self.priority = priority
    self.description = description
  #下面两个方法重写一个就可以了
  def __lt__(self,other):#operator < 
    return self.priority < other.priority
  def __cmp__(self,other):
    #call global(builtin) function cmp for int
    return cmp(self.priority,other.priority)
  def __str__(self):
    return '(' + str(self.priority)+',\'' + self.description + '\')'

def PriorityQueue_class():
  que = Q.PriorityQueue()
  skill5 = Skill(5,'proficient')
  skill6 = Skill(6,'proficient6')
  que.put(skill6)
  que.put(Skill(5,'proficient'))
  que.put(Skill(10,'expert'))
  que.put(Skill(1,'novice'))
  while not que.empty():
    print que.get(),
  print

其他的一些方法的使用还是需要参考给出的文档的。

最后一点,让我比较奇怪的是(可能我并没有找到),没有提供像排序函数那样,指定比较方法函数,这点和c++有点区别。

这篇文档参考:参考文档

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Unicode和Python的中文处理
Mar 19 Python
python中numpy包使用教程之数组和相关操作详解
Jul 30 Python
PyQt5每天必学之像素图控件QPixmap
Apr 19 Python
python画图系列之个性化显示x轴区段文字的实例
Dec 13 Python
django框架基于queryset和双下划线的跨表查询操作详解
Dec 11 Python
python字符串,元组,列表,字典互转代码实例详解
Feb 14 Python
使用sklearn的cross_val_score进行交叉验证实例
Feb 28 Python
python实现图片横向和纵向拼接
Mar 05 Python
python文件操作seek()偏移量,读取指正到指定位置操作
Jul 05 Python
python利用platform模块获取系统信息
Oct 09 Python
Python之京东商品秒杀的实现示例
Jan 06 Python
Python实现抖音热搜定时爬取功能
Mar 16 Python
Python两个字典键同值相加的几种方法
Mar 05 #Python
详解python算法之冒泡排序
Mar 05 #Python
Python字符串通过'+'和join函数拼接新字符串的性能测试比较
Mar 05 #Python
Python实现KNN(K-近邻)算法的示例代码
Mar 05 #Python
Python按钮的响应事件详解
Mar 04 #Python
Python中三元表达式的几种写法介绍
Mar 04 #Python
Python生成器的使用方法和示例代码
Mar 04 #Python
You might like
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
php笔记之:初探PHPcms模块开发介绍
2013/04/26 PHP
PHP处理会话函数大总结
2015/08/05 PHP
Yii2.0实现生成二维码功能实例
2017/10/24 PHP
游览器中javascript的执行过程(图文)
2012/05/20 Javascript
让html页面不缓存js的实现方法
2014/10/31 Javascript
浅谈javascript中createElement事件
2014/12/05 Javascript
node.js中的buffer.copy方法使用说明
2014/12/14 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
jQuery on()绑定动态元素出现的问题小结
2016/02/19 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
Vue模拟数据,实现路由进入商品详情页面的示例
2018/08/31 Javascript
小程序绑定用户方案优化小结
2019/05/15 Javascript
JS实现炫酷雪花飘落效果
2020/08/19 Javascript
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
ant design pro中可控的筛选和排序实例
2020/11/17 Javascript
python实现k均值算法示例(k均值聚类算法)
2014/03/16 Python
Python标准模块--ContextManager上下文管理器的具体用法
2017/11/27 Python
Python判断一个文件夹内哪些文件是图片的实例
2018/12/07 Python
对Python 除法负数取商的取整方式详解
2018/12/12 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
2019/06/11 Python
python中的global关键字的使用方法
2019/08/20 Python
python连接PostgreSQL数据库的过程详解
2019/09/18 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
Pytest测试框架基本使用方法详解
2020/11/25 Python
英国著名的小众美容品牌网站:Alyaka
2017/08/08 全球购物
捷克汽车配件和工具销售网站:TorriaCars
2018/02/26 全球购物
哄娃神器4moms商店:美国婴童用品品牌
2019/03/07 全球购物
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
银行会计职员个人的自我评价
2013/09/29 职场文书
企业读书活动总结
2014/06/30 职场文书
事业单位人员的自我评价范文
2014/09/21 职场文书
2014大学生党员评议个人总结
2014/09/22 职场文书
学校党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
初中数学教学随笔
2015/08/15 职场文书