優先隊列
優先隊列的出隊與隊列一樣,均是從隊首出隊,但是在優先隊列內部,數據項的次序是由“優先級”來確定:高優先級的數據在隊首,低優先級的數據項則排在後面。
優先隊列的實現——二叉堆(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