python3.5
最優時間複雜度:nlogn
最壞時間複雜度:nlogn
輔助空間:O(1)
穩定性:不穩定
1.堆排序思想:
a.將無序序列構成一個堆,根據升序和降序需求選擇大頂堆和小頂堆(大頂堆降序)
b.將堆頂元素與末尾元素交換,將最大元素"沉"到數組的末端;
c.重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,反覆執行調用+交換的步驟,直到整個序列有序
2.python代碼實現
def big_endian(arr, start, end):
root = start
while True:
child = root * 2 + 1 # 左孩子
if child > end: # 孩子比最後一個節點還大 也就意味着最後一個葉子節點了 就得跳出去一次循環已經調整完畢
break
if child + 1 <= end and arr[child] < arr[child + 1]: # 爲了始終讓其跟子元素的較大值比較 如果右邊大就左換右,左邊大的話就默認
child += 1
if arr[root] < arr[child]: # 父節點小於子節點直接換位置 同時座標也得換這樣下次循環可以準確判斷是否爲最底層是不是調整完畢
arr[root], arr[child] = arr[child], arr[root]
root = child
else: # 父子節點順序正常 直接過
break
def heap_sort(arr):
# 無序區大根堆排序
first = len(arr) // 2 - 1
for start in range(first, -1, -1): # 從下到上,從右到左對每個節點進調整 循環得到非葉子節點
big_endian(arr, start, len(arr) - 1) # 去調整所有的節點
for end in range(len(arr) - 1, 0, -1):
arr[0], arr[end] = arr[end], arr[0] # 頂部尾部互換位置
big_endian(arr, 0, end - 1) # 重新調整子節點的順序 從頂開始調整
return arr
def main():
l = [3, 1, 4, 9, 6, 7, 5, 8, 2, 10]
print(heap_sort(l)) #原地排序
if __name__ =="__main__":
main()