二叉堆和堆排序的python實現

2021-10-06 01:37:02 字數 4694 閱讀 3913

二叉堆本質上是一種完全二叉數:

二叉堆建立:

根據原陣列,然後從最後乙個非葉子節點開始,依次下沉,得到最後序列

二叉堆操作:

圖比較麻煩就不畫了,可以參考這篇文章:二叉堆**

# 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.每個節點的左子樹和右子樹都是乙個二叉堆 都是最大堆或者是最小堆 當父節點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆,總是小於或等於任何乙個子節點的鍵值時為最小堆...

序列化二叉堆與二叉堆排序

二叉堆分為最大堆與最小堆,一組不規則的完全二叉樹或者近完全二叉樹,可以通過調整稱為二叉堆。序列化 形成二叉堆通過下沉。插入元素通過上浮。排序 二叉堆的最大堆為父節點一定大於或者等於子節點,堆頂一定最大。如果最小堆的堆頂與最後乙個元素互動,那麼最後乙個元素一定最大。如果最後乙個元素不參加排序,那麼是一...