最小堆实现优先队列:Python实现
最小堆实现优先队列:Python实现
堆是一种数据结构,因为Heapsort而被提出。除了堆排序,“堆”这种数据结构还可以用于优先队列的实现。
堆首先是一个完全二叉树:它除了最底层之外,树的每一层的都是满的,且最底层中的节点处于左边,相互之间没有“跳变”;其次,堆有次序属性:每个节点中的数据项都大于或者等于其子女的数据项(如果是记录,则这些记录中的某个关键域必须满足这一属性)。 当然,这是指大顶堆,小顶堆则是父节点比子节点都要小。
所谓队列,就是一个FIFO表(first in, first out)。优先队列,就是在队列的基础上,每个元素加一个优先级,last in的元素可能会first out,这就是优先级在起作用。
我想实现这样一个优先队列:
元素为整数
元素值小的优先级反而大
有入队操作,每次进入一个元素
出队操作,也行每次一个元素
那么,我的小根堆Heap应该这样考虑:
每当插入元素时,在原有Heap的最后一个叶子节点后面插入新元素val,并持续比较val和其父节点的值之间是否满足堆的次序属性,直到满足
每当删除元素时,删除的是值最小的元素,也就是根结点root,则将root和最后一个叶子节点lastleaf互换,然后删除交换后的new_lastleaf ,并从new_root开始调整堆,使满足堆的次序属性。
这样一来,代码就不难写出:
#coding:utf8#author:HaxtraZ#description:优先队列,用堆实现#修改自《算法导论》2nd EditionclassZHeap:def __init__(self, item=[]):# 初始化。item为数组self.items = item
self.heapsize = len(self.items)def LEFT(self, i):return2* i +1def RIGHT(self, i):return2* i +2def PARENT(self, i):return(i -1)/2def MIN_HEAPIFY(self, i):# 最小堆化:使以i为根的子树成为最小堆
l =self.LEFT(i)
r =self.RIGHT(i)if l <self.heapsize andself.items[l]<self.items[i]:
smallest = l
else:
smallest = i if r <self.heapsize andself.items[r]<self.items[smallest]:
smallest = r if smallest != i:self.items[i],self.items[smallest]=self.items[smallest],self.items[i]self.MIN_HEAPIFY(smallest)def INSERT(self, val):# 插入一个值val,并且调整使满足堆结构self.items.append(val)
idx = len(self.items)-1
parIdx =self.PARENT(idx)while parIdx >=0:ifself.items[parIdx]>self.items[idx]:self.items[parIdx],self.items[idx]=self.items[idx],self.items[parIdx]
idx = parIdx
parIdx =self.PARENT(parIdx)else:breakself.heapsize +=1def DELETE(self):last= len(self.items)-1iflast<0:# 堆为空returnNone# else:self.items[0],self.items[last]=self.items[last],self.items[0]
val =self.items.pop()self.heapsize -=1self.MIN_HEAPIFY(0)return val def BUILD_MIN_HEAP(self):# 建立最小堆, O(nlog(n))
i =self.PARENT(len(self.items)-1)while i >=0:self.MIN_HEAPIFY(i)
i -=1def SHOW(self):printself.items classZPriorityQ(ZHeap):def __init__(self, item=[]):ZHeap.__init__(self, item)def enQ(self, val):ZHeap.INSERT(self, val)def deQ(self):
val =ZHeap.DELETE(self)return val a =[1,3,2,4,8,6,22,9]
pq =ZPriorityQ()
n = len(a)for i in range(n):
pq.enQ(a[i])
pq.SHOW()for i in range(n):
pq.deQ()
pq.SHOW()
其中,ZHeap表示小根堆,ZPriorityQ表示优先队列,deQ表示退队,enQ表示入队。
我们发现以下结论:大根堆用于升序排序,小根堆用于降序排序。
为什么用堆来实现优先队列?原因只有一个:复杂度低。
如果使用列表(存放在list中),插入为O(1),删除为O(n);
如果使用按照优先级排好序的有序列表,插入和线性插入排序一样,O(n),删除则为O(1)
使用堆的时候,无论你删除还是插入,都是O(lg n)时间复杂度,对于插入和删除都比较频繁的操作来讲,这是最好不过的了。
如果认为有不正确的地方欢迎拍砖。
最小堆实现优先队列:Python实现的更多相关文章
- PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分)
PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分) 对于给定的最小堆(优先队列),分别实现插入元素和删除堆顶的函数. 函数接口定义: int insertIntoHeap(struct Hea ...
- c++/java/python priority_que实现最大堆和最小堆
#include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...
- Black Box--[优先队列 、最大堆最小堆的应用]
Description Our Black Box represents a primitive database. It can save an integer array and has a sp ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- Python3实现最小堆建堆算法
今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...
- 【数据结构】通用的最小堆(最大堆)D-ary Heap
听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100, ...
- 基于condition 实现的线程安全的优先队列(python实现)
可以把Condiftion理解为一把高级的琐,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题.threadiong.Condition在内部维护一个琐对象(默认是RL ...
- Java数据结构之堆和优先队列
概述 在谈堆之前,我们先了解什么是优先队列.我们每天都在排队,银行,医院,购物都得排队.排在队首先处理事情,处理完才能从这个队伍离开,又有新的人来排在队尾.但仅仅这样就能满足我们生活需求吗,明显不能. ...
随机推荐
- 我们的空间是它圆——基于Poicare对宇宙的模型
一般 状态 在人类文明的开始,并探讨了空间和时间的混乱从来没有停止过.马跑得更快.鱼下潜深.鸟振翅高飞,但是,人类并没有很深的不满潜飞不高.为什么?其原因是,马跑得更快,但它不会不知道他们为什么会跑得 ...
- PsExec.exe执行远程程序
PsExec.exe \\192.168.1.1 -u username -p password -i -d -s c:\Windows\system32\NETSTAT.exe -a
- 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据
原文:[百度地图API]如何利用地图API制作汽车沿道路行驶的动画?--如何获得道路层数据 有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画.可是,百度地图的道路数据并没有公开 ...
- windows7股票的,win8残疾人,安装Han澳大利亚sinoxn个时间,sinox它支持大多数windows软体
腾讯科技: 正如先前所宣布,微软,10一个月31迄今,Windows 7家庭基础版.家庭高级版和旗舰版盒装版本将不再销售.而微软是不会再OEM制造商授予许可数量的三个版本. windows7股票的.由 ...
- VS2015前端工具:NPM和Web Essentials
VS2015前端工具:NPM和Web Essentials 1.写作背景 想在5月份前换个工作环境了,“检讨”一下自己混饭的技术水平和处世的人脉关系,觉得很不给力!为人方面,人各有志也就不纠结了,但本 ...
- NET 2015
.NET 2015 英文原文:Understanding .NET 2015 Understanding 翻译为了解或理解,对于 .NET 来说,2015 年注定会更加精彩,所以标题就用了“精彩”这个 ...
- 【ThinkingInC++】66、pointer Stash的使用
头文件PStash.h /** * 书本:[ThinkingInC++] * 功能:pointer Stash的头文件 * 时间:2014年10月5日14:33:15 * 作者:cutter_poin ...
- 当今最流行的Node.js应用开发框架简介
快速开发而又容易扩展,高性能且鲁棒性强.Node.js的出现让所有网络应用开发者的这些梦想成为现实.但是,有如其他新的开发语言技术一样,从头开始使用Node.js的最基本功能来编写代码构建应用是一个非 ...
- C语言宏的高级应用
原文:C语言宏的高级应用 关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号.比如 ...
- [译]Java 设计模式之命令
(文章翻译自Java Design Pattern: Command) 命令设计模式在进行执行和记录的时候需要一个操作及其参数和封装在一个对象里面.在下面的例子中,命令是一个操作,它的参数是一个Com ...