排序演算法 堆排序

2021-10-09 11:39:03 字數 2036 閱讀 3200

話不多說,看**。參考鏈結

def

build_max_heap

(heap)

:# 構造乙個堆,將堆中所有資料重新排序

heapsize =

len(heap)

for i in

range

((heapsize -2)

//2,-

1,-1

):# 自底向上建堆

max_heapify(heap, heapsize, i)

defmax_heapify

(heap,heapsize,root)

:# 調整列表中的元素並保證以root為根的堆是乙個大根堆

''' 給定某個節點的下標root,這個節點的父節點、左子節點、右子節點的下標都可以被計算出來。

父節點:(root-1)//2

左子節點:2*root + 1

右子節點:2*root + 2 即:左子節點 + 1

'''left =

2*root +

1 right = left +

1 larger = root

if left < heapsize and heap[larger]

< heap[left]

: larger = left

if right < heapsize and heap[larger]

< heap[right]

: larger = right

if larger != root:

# 如果做了堆調整則larger的值等於左節點或者右節點的值,這個時候做堆調整操作

heap[larger]

, heap[root]

= heap[root]

, heap[larger]

# 遞迴的對子樹做調整

max_heapify(heap, heapsize, larger)

defheap_sort

(heap)

:# 將根節點取出與最後一位做對調,對前面len-1個節點繼續進行堆調整過程。

build_max_heap(heap)

# 調整後列表的第乙個元素就是這個列表中最大的元素,將其與最後乙個元素交換,然後將剩餘的列表再遞迴的調整為最大堆

for i in

range

(len

(heap)-1

,-1,

-1):

heap[0]

, heap[i]

= heap[i]

, heap[0]

max_heapify(heap, i,0)

import heapq

# 測試

if __name__ ==

'__main__'

: a =[30

,50,57

,94,80

,84,77

,62,78

]print

(a) heap_sort(a)

print

(a) b = a[:]

heapq.heapify(b)

print

(b) res =

for i in

range

(len

(a)):)

print

(res)

好了。

時間複雜度

堆排序的時間複雜度分為兩個部分乙個是建堆的時候所耗費的時間,乙個是進行堆調整的時候所耗費的時間。而堆排序則是呼叫了建堆和堆調整。

剛剛在上面也提及到了,建堆是乙個線性過程,從len/2-0一直呼叫堆調整的過程,相當於o(h1)+o(h2)+…+o(hlen/2)這裡的h表示節點深度,len/2表示節點最大深度,對於求和過程,結果為線性的o(n) 。

堆調整為乙個遞迴的過程,調整堆的過程時間複雜度與堆的深度有關係,相當於lgn的操作。

因為建堆的時間複雜度是o(n),調整堆的時間複雜度是o(lgn),所以堆排序的時間複雜度是o(nlgn)。

排序演算法 堆排序

1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...

排序演算法 堆排序

花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...

排序演算法 堆排序

由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...