优先队列
优先队列的出队与队列一样,均是从队首出队,但是在优先队列内部,数据项的次序是由“优先级”来确定:高优先级的数据在队首,低优先级的数据项则排在后面。
优先队列的实现——二叉堆(Binary Heap)
二叉堆逻辑结构上像二叉树,却是用非嵌套的列表来实现。
二叉堆能够将优先队列的入队和出队复杂度都保持在O(log n)。
用非嵌套列表来实现二叉堆
(1)为了使堆操作能保持在对数水平上,就必须采用二叉树结构。
(2)若要使操作始终保持在对数级别,就需要始终保持二叉树的“平衡”。:树根左右子树拥有数量相同的节点
基于此,我们采用“完全二叉树”的结构来近似实现平衡。
完全二叉树的性质:任何一个节点x,其父节点p中的key均小于x中的key。这样,(1)根节点的key最小
(2)完全二叉树中任何一条路径,均是一个已排序的数列。
二叉堆的python实现
###二叉堆的初始化
class BinHeap:
def __init__(self):
self.heaplist=[0] #采用一个列表来保存堆数据,表首下标为0的项无用,为了后续整除,任保留它
self.currentsize=0
## 建立二叉堆:从无序表生成“堆”
def buildHeap(self,alist):
i = len(alist) // 2
self.currentSize = len(alist)
self.heapList = [0] + alist[:]
while (i > 0):
self.percDown(i)
i = i - 1
## insert(key)实现
#新key加在队列末尾,无法保持堆次序,因此需要将key沿着路径上移到其正确位置。
def insert(self,new_item):
self.item_list.append(new_item)
self.item_list[0]+=1
self.upward_adjust(self.item_list[0])
def upward_adjust(self,index):
while index//2>0:
if self.item_list[index]<self.item_list[index//2]:
temp = self.item_list[index]
self.item_list[index]=self.item_list[index//2]
self.item_list[index//2]=temp
index = index//2
else:
break
## delMin(key)实现
#堆次序(最小堆)要求根节点是树中最小的元素,因此很容易找到最小项。
#比较困难的是移走根节点的元素后如何保持堆结构和堆次序,我们可以分两步走。首先,用最后一个节点来代替根节点。移走最后一个节点保持了堆结构的性质。这么简单的替换,还是会破坏堆次序。那么第二步,将新节点“下沉”来恢复堆次序。
def percDown(self,i):
while (i * 2) <= self.currentSize:
mc = self.minChild(i)
if self.heapList[i] > self.heapList[mc]:
tmp = self.heapList[i]
self.heapList[i] = self.heapList[mc]
self.heapList[mc] = tmp
i = mc
def minChild(self,i):
if i * 2 + 1 > self.currentSize:
return i * 2
else:
if self.heapList[i*2] < self.heapList[i*2+1]:
return i * 2
else:
return i * 2 + 1
def delMin(self):
item=self.heapList[1]
self.heapList[1]=self.heapList[self.currentSize]
self.currentSize-=1
self.heapList.pop()
self.percDown(1)
return item
##判断堆是否为空
def isEmpty(self):
return 0 == self.item_list[0]
# 返回堆中的项数
def size(self):
return self.item_list[0]
#测试例
bh = BinHeap()
bh.buildHeap([9,5,6,2,3])
print(bh.delMin())
参考文献:https://www.icourse163.org/learn/PKU-1206307812?tid=1450242471#/learn/content?type=detail&id=1214420560&cid=1218119415