資料結構-堆(python實現)
用list來儲存堆元素,表尾端加入元素,首段作為堆頂(借鑑裘老師資料結構與演算法的書加上自己的理解)
# 堆:就是乙個完全二叉樹
class
heap
(object):
def__init__
(self, elist)
: self._elems =
list
(elist)
if elist:
self.buildheap(
)def
is_empty
(self)
:return
not self._elems
defpeek
(self)
:# 取堆頂的元素,並不是把堆頂元素給彈出
if self.is_empty():
raise valueerror(
'堆為空!'
)return self._elems[0]
defpush
(self, e)
:# 新插入乙個元素,鏈結在完全二叉樹最下層最右邊
none
)# 增加乙個位置
self.siftup(e,
len(self._elems)-1
)# 引數為新元素的值和列表的最後一位的下標值
""" 對於陣列裡的乙個下標 i,我們可以得到它的父親和孩子的節點對應的下標:(見書193頁)
parent = int((i-1) / 2) # 取整
left = 2 * i + 1
right = 2 * i + 2
"""defsiftup
(self, e, last)
:# e就是要上浮的元素,依次與它的父節點的值進行比較,last的值是最後乙個元素e的下標值,也就是列表的最大下標
elems, i, j = self._elems, last,
(last-1)
//2# j是最後乙個結點即i的父節點
while i >
0and e < elems[j]
:# e的值比e的父節點的值小
elems[i]
= elems[j]
# 把e的父節點的值下移和原來的e交換
i, j = j,
(j-1)//
2# 此時i為原來e的父節點的下標值,j為原來e的父節點的父節點的下標值,即再比較e與更上一層父節點的值
elems[i]
= e # 直到找不到比e小的父節點,就將e插入到此處,也就是鏈結到此父節點下
defpop
(self)
:if self.is_empty():
raise valueerror
elems = self._elems
e0 = elems[0]
# 堆頂是最優先元素,首先取出它的值,此時原來堆已經不是乙個完整的堆了
e = elems.pop(
)# list的pop首先彈出最後面乙個元素,給e放在堆頂再下沉恢復堆中元素的順序,去重新構成乙個完整的堆
iflen
(elems)
>0:
self.siftdown(e,0,
len(elems)
)"""
siftdown:始終比較父節點和兩個子節點的值,將小的往下放,然後將堆排好序,siftdown也是拿著元素去找位置,而不是先插入再去逐個交換
"""defsiftdown
(self, e, begin, end)
:# e是最後那個元素,begin是下標0,end是彈出堆頂後總的元素個數
elems , i, j = self._elems, begin, begin*2+
1# i=0,j是i的子節點
while j < end:
# 知道j還沒到最後乙個結點的下標值
if j+
1< end and elems[j+1]
< elems[j]
:# 並且j的兄弟節點也不是最後乙個結點,且左節點的值大於右節點的值
j +=
1# 如果左節點的值小於右節點的值,那麼e將會和它的右子節點換
if e < elems[j]
:# 如果e的值比e的子節點的值大,就將j結點往上提,大的在堆頂,小的往下放
break
elems[i]
= elems[j]
# elems[j]在三者中最小,上移,將j下標的值放在了堆頂,i=0為堆頂下標,但是各個元素的下標值沒變
i = j # 將堆頂結點的子節點下標j給i,表示將會將e插在此處
j = j *2+
1# 將j換成原來j子節點的下標值,然後while再去比較子節點值和e的大小,看看要不要交換,總之小的往下挪
elems[i]
= e # 如果e的子節點沒有比e更小的值,e就插入到i處,
defbuildheap
(self)
:# 用乙個元素的序列已經是堆的list去建立初始堆
end =
len(self._elems)
for i in
range
(end//2,
-1,-
1): self.siftdown(self._elems[i]
, i, end)
# 從列表的一半下標處通過向下篩選開始建立堆,
# 因為從end//2開始後面都是完全二叉樹的葉子節點,也就是每乙個已經是乙個堆
# 所以每一步就是在兩個已有的堆上面加上乙個根元素,並通過向下篩選調整成乙個堆
資料結構 堆的實現
普通的模板引數 template struct less template struct greater template 預設為小堆 class heap heap const t array,size t size int root heap.size 2 1 for root 0 root s...
(資料結構)堆的實現
堆總是一棵完全二叉樹 且 最大堆總滿足,堆中父節點的值總是大於等於其左右子節點的值 最小堆總滿足,堆中父節點的值總是小於等於其左右子節點的值。1.資料儲存 如下圖所示,如果自頂向下,自左向右依次將完全二叉樹中的每個節點標上序號 注 此處從1開始 並使用陣列儲存 注 陣列中下標0對應的位置未放置元素 ...
資料結構 棧 佇列 堆的python實現
二 佇列的python實現 三 堆的python實現 棧 佇列 堆是基礎的資料結構型別,其中棧是後進先出的資料結構 佇列是先進先出的資料結構 堆通常可以被看成一棵樹,又可以被分為最小堆和最大堆,最小堆是指堆中某個節點的元素總不大於其父節點的值 最大堆是指堆中某個元素總不小於其父節點的值。列表 lis...