二叉堆本質上是一種完全二叉數:
二叉堆建立:
根據原陣列,然後從最後乙個非葉子節點開始,依次下沉,得到最後序列
二叉堆操作:
圖比較麻煩就不畫了,可以參考這篇文章:二叉堆**
# 1.二叉堆實現
'''儲存方式:利用陣列順序儲存
定位方法:利用陣列下標進行定位(父節點parent,左子樹:2*parent+1,右子樹:2*parent+2)
'''class
minheap
:def
__init__
(self)
: self.heap=
#上浮調整函式
defshift_up
(self)
: childindex =
len(self.heap)-1
parentindex =
(childindex-1)
//2#temp 儲存插入的子節點的值,用於最後賦值
temp = self.heap[childindex]
while childindex>
0and temp: self.heap[childindex]
= self.heap[parentindex]
childindex = parentindex
parentindex =
(childindex-1)
//2self.heap[childindex]
= temp
#下沉調整函式,節點id:parentindex
defshift_down
(self,parentindex)
:#temp儲存父節點的值,用於最後賦值
temp = self.heap[parentindex]
childindex =
2*parentindex+
1while childindex<
len(self.heap)
:#如果有右孩子且左孩子大於右孩子,則定位到右孩子
if childindex+
1<
len(self.heap)
and self.heap[childindex]
>self.heap[childindex+1]
: childindex +=
1#如果父節點小於任一子節點,則退出迴圈
if temp<=self.heap[childindex]
:break
self.heap[parentindex]
= self.heap[childindex]
parentindex = childindex
childindex = parentindex*2+
1 self.heap[parentindex]
= temp
#構造推
defbuildheap
(self,alist)
:#從最後乙個非葉子節點開始,依次下沉
self.heap = alist
for i in
range((
len(self.heap)-2
)//2,
-1,-
1): self.shift_down(i)
#定義插入節點函式,
definsert
(self,num)
: self.shift_up(
)#刪除堆頂元素
defdelmin
(self)
: retrval = self.heap[0]
self.heap[0]
= self.heap[
len(self.heap)-1
]
self.heap.pop(
) self.shift_down(0)
return retrval
bh = minheap(
)bh.insert(1)
bh.insert(8)
bh.insert(4)
bh.insert(3)
bh.insert(2)
bh.heap
[1, 2, 4, 8, 3]
bh1 = minheap(
)bh1.buildheap([1
,8,4
,3,2
])bh1.heap
[1, 2, 4, 3, 8]
bh1.insert(5)
bh1.insert(6)
bh1.heap
[1, 2, 4, 3, 8, 5, 6]
bh1.delmin(
)# 返回 1
bh1.delmin(
)# 返回 2
bh1.heap
# 返回 [3, 5, 4, 6, 8]
插入和刪除的操作都是 o(logn)
生成二叉樹的操作為 o(n),至於為什麼為o(n),可以參照以下文章
堆排序利用了二叉堆的堆頂為最大或最小的特性。
演算法步驟
#堆排序(降序)
# 生成最小堆
class
heapsort
:def
__init__
(self)
: self.heap=
#上浮調整函式
defshift_up
(self)
: childindex =
len(self.heap)-1
parentindex =
(childindex-1)
//2#temp 儲存插入的子節點的值,用於最後賦值
temp = self.heap[childindex]
while childindex>
0and temp: self.heap[childindex]
= self.heap[parentindex]
childindex = parentindex
parentindex =
(childindex-1)
//2self.heap[childindex]
= temp
#下沉調整函式,節點id:parentindex
defshift_down
(self,parentindex,length)
:#temp儲存父節點的值,用於最後賦值
temp = self.heap[parentindex]
childindex =
2*parentindex+
1while childindex< length :
#如果有右孩子且左孩子大於右孩子,則定位到右孩子
if childindex+
1< length and self.heap[childindex]
>self.heap[childindex+1]
: childindex +=
1#如果父節點小於任一子節點,則退出迴圈
if temp<=self.heap[childindex]
:break
self.heap[parentindex]
= self.heap[childindex]
parentindex = childindex
childindex = parentindex*2+
1 self.heap[parentindex]
= temp
#構造推
defbuildheap
(self,alist)
:#從最後乙個非葉子節點開始,依次下沉
self.heap = alist
for i in
range((
len(self.heap)-2
)//2,
-1,-
1): self.shift_down(i,
len(self.heap)
)def
sort
(self,array)
:# 1.構造二叉堆
self.buildheap(array)
# 2.迴圈刪除堆頂,移到尾部,調整產生新的堆頂
for i in
range
(len
(self.heap)-1
,-1,
-1):
temp = self.heap[i]
self.heap[i]
= self.heap[0]
self.heap[0]
= temp
# 下沉調整堆頂
self.shift_down(
0,i)
return self.heap
hs = heapsort(
)hs.sort([1
,5,2
,8,4
,9,7
])# [9, 8, 7, 5, 4, 2, 1]
二叉堆和堆排序
二叉 堆是乙個陣列,它可以近似看作完全二叉樹。樹上的每乙個節點對應陣列中的乙個元素。除了最底層,該樹是完全充滿的,而且是從左向右填充。根據節點下標可以求出對應的子樹和雙親 parent i return i 2 i表示陣列中的第幾個元素,i 2 表示取整數 left i return 2 i rig...
新手講排序 堆排序 和 認識二叉堆
二叉堆是完全二叉樹或者是近似完全二叉樹 二叉堆滿足的二個特性 1.父節點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2.每個節點的左子樹和右子樹都是乙個二叉堆 都是最大堆或者是最小堆 當父節點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆,總是小於或等於任何乙個子節點的鍵值時為最小堆...
序列化二叉堆與二叉堆排序
二叉堆分為最大堆與最小堆,一組不規則的完全二叉樹或者近完全二叉樹,可以通過調整稱為二叉堆。序列化 形成二叉堆通過下沉。插入元素通過上浮。排序 二叉堆的最大堆為父節點一定大於或者等於子節點,堆頂一定最大。如果最小堆的堆頂與最後乙個元素互動,那麼最後乙個元素一定最大。如果最後乙個元素不參加排序,那麼是一...