個(gè)人技術(shù)博客地址:http://songmingyao.com/
原理
- 將列表構(gòu)造成最大堆或最小堆
- 將堆的根節(jié)點(diǎn),即最大值或最小值與堆的末尾對(duì)調(diào)
- 將末尾元素(即之前得到的堆的根節(jié)點(diǎn))移除后,重構(gòu)堆,如此循環(huán)
源碼
def heap_sort(l):
def max_heapify(root_index, end_index):
"""函數(shù)用于構(gòu)造最大堆"""
# 減一是因?yàn)槎训南聵?biāo)從1開(kāi)始
max_child_index = root_index*2-1
# 在該二叉樹(shù)有兩個(gè)子節(jié)點(diǎn)的情況下,將兩個(gè)子節(jié)點(diǎn)比較大小
if max_child_index + 1 < end_index:
if l[max_child_index+1] > l[max_child_index]:
max_child_index += 1
# 將最大的子節(jié)點(diǎn)與根節(jié)點(diǎn)做比較
if l[max_child_index] > l[root_index-1]:
l[max_child_index], l[root_index-1] = l[root_index-1], l[max_child_index]
# 循環(huán)構(gòu)造最大堆,而后將最大堆的根節(jié)點(diǎn)與末節(jié)點(diǎn)調(diào)換
for end_index in range(len(l), 1, -1):
# 每次要構(gòu)造的最大堆大小與末節(jié)點(diǎn)有關(guān)
max_root_index = end_index//2
# 構(gòu)造一個(gè)最大堆
for root_index in range(max_root_index, 0, -1):
max_heapify(root_index, end_index)
# 將最大堆的根節(jié)點(diǎn)與末節(jié)點(diǎn)調(diào)換
l[0], l[end_index-1] = l[end_index-1], l[0]
if __name__ == '__main__':
l = [6, 5, 2, 8, 9, 4, 1, 0, 3, 7]
print(l)
heap_sort(l)
print(l)
時(shí)間復(fù)雜度
- 最優(yōu)時(shí)間復(fù)雜度:O(nlogn)
- 最壞時(shí)間復(fù)雜度:O(nlogn)
- 穩(wěn)定性(多個(gè)元素等值的情況下是否會(huì)破壞原有順序):不穩(wěn)定