# 調整某乙個節點到具體的位置,確保堆頂為最大值,時間複雜度為logn
def heapify(arr, idx, end):
# size = len(arr)
left = idx * 2 + 1
right = left + 1
while left <= end: # 當前節點非葉子結點
max_idx = idx
if arr[left] > arr[max_idx]:
max_idx = left
if right <= end and arr[right] > arr[max_idx]:
max_idx = right
if idx == max_idx: # 如果不用交換則break,說明已經交換結束
break
arr[idx], arr[max_idx] = arr[max_idx], arr[idx] # 將父子三個節點中,最大的值放到父節點
idx = max_idx # 繼續調整子樹
left = idx * 2 + 1
right = left + 1
# 讓乙個無序陣列變成大根堆, 時間複雜度為n*logn
def build_heap(arr):
size = len(arr)
for i in range((size - 2) // 2, -1, -1): # (size-2)//2 是最後乙個非葉節點,葉節點不用調整
heapify(arr, i, size - 1)
return arr
# 公升序堆排序,思路為先建堆,然後讓堆頂最大元素和最後乙個交換,然後繼續調整第乙個到倒數第二個元素,獲取最大值,再交換
# 時間複雜度為n*logn + n*logn = n*logn
def heap_sort(arr):
build_heap(arr)
size = len(arr)
for i in range(size):
arr[0], arr[size - i - 1] = arr[size - i - 1], arr[0]
heapify(arr, 0, size - i - 2)
return arr
print(heap_sort([3, 2, 1]))
堆排序 模板 堆排序
biu 堆排序是乙個不穩定的排序演算法,對資料不敏感,時間複雜度穩定,主要分為兩部分 建堆 堆排序。其中建堆的時間複雜度是 o n o n o n 的,而排序選出乙個最大 最小值的過程是 o l ogn o logn o logn 的,一共需要n次操作,故總共的時間複雜度是 o n logn o n...
堆排序 模板
很認真地看完了 算導 的排序之前的所有部分,除了演算法複雜度那一章的數學要求太高,難以完全駕馭以外,其他的部分還是很好理解的。爭取把 算導 裡面出現的演算法都自己實現,製作自己的模板,以後好用。堆排序雖然在一般的時候是沒有快排好用,但是在優先佇列裡面很好用,所以也是很有力的 這個堆排序模板是我基本完...
堆排序模板
最小堆刪除堆頂法排序 include int n 儲存堆中的陣列的個數 int h 101 存放堆的陣列 void swap x,y 交換堆中的兩個元素 void shiftdown int i 第i個位置向下調整 if t i else flag 1 return void creat intde...