step1: 構建堆
從最後乙個非葉子結點開始向下調整,使其成為乙個堆
step2: 挨個出數
堆構建完後,得到堆頂,即為最大的元素
1) 將堆頂和堆的最後乙個元素互換
2) 再使用向下調整,使其成為乙個新堆
3) 調整完成後,得到第二大的元素
4) 從 1
) 開始重複,直到堆為空
最壞情況:o(nlogn)
平均情況:o(nlogn)
最好情況:o(nlogn)
o(
1)
不穩定
複雜
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""堆排序
思路: step1: 構建堆
從最後乙個非葉子結點開始向下調整,使其成為乙個堆
step2: 挨個出數
堆構建完後,得到堆頂,即為最大的元素
1) 將堆頂和堆的最後乙個元素互換
2) 再使用向下調整,使其成為乙個新堆
3) 調整完成後,得到第二大的元素
4) 從 1) 開始重複,直到堆為空
時間複雜度:
最壞情況:o(nlogn)
平均情況:o(nlogn)
最好情況:o(nlogn)
空間複雜度:o(1)
穩定性:不穩定
複雜性:複雜
"""import random
# 向下調整
defsift
(ls, low, high)
:"""向下調整函式
如果乙個堆的根節點左右子樹都是堆,但其本身不是堆,
則通過向下調整使其成為堆
args:
:param ls: list, 待調整的列表
:param low: int, 當前堆的根節點
:param high: int, 當前堆的最後乙個元素
"""i = low
j =2* i +
1# 預設指向左孩子
tmp = ls[low]
while j <= high:
# 只要j位置上有數
if j +
1<= high and ls[j +1]
> ls[j]
:# 右孩子存在且比較大
j +=
1# j指向右孩子
if ls[j]
> tmp:
ls[i]
= ls[j]
# 更新堆頂
# 往下走一層,決定tmp去哪
i = j
j =2* i +
1else
: ls[i]
= tmp
break
else
: ls[i]
= tmp
# 堆排序
defheap_sort
(ls)
:"""堆排序
完成構建堆以及挨個出數兩個功能
args:
:param ls: list, 待排序的列表
"""# 構建堆
# 從最後乙個非葉子節點開始調整
# 最後乙個非葉子節點 (n - 1) // 2
# 注意: 這裡的n代表的是列表最後乙個元素的下標
# n = len(ls) - 1; (n - 1) // 2
# 所以經整合以及化簡得到 n // 2 - 1
n =len(ls)
for i in
range
(n //2-
1,-1
,-1)
: sift(ls, i, n -1)
# 挨個出數
for i in
range
(n -1,
-1,-
1): ls[0]
, ls[i]
= ls[i]
, ls[0]
sift(ls,
0, i -1)
ls =
[_ for _ in
range(20
)]random.shuffle(ls)
heap_sort(ls)
print
(ls)
python排序演算法之堆排序
堆是種完全二叉樹,每個結點的值都大於或等於其左右孩子結點值的堆稱為大頂堆 反之,每個結點的值都小於或等於其左右孩子結點的值稱為小頂堆。堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序複雜度均為o nlogn 當堆父節點的下標為i時,其左孩子的下標為2i 1,右孩子的下標為2i 2,大頂堆 a...
python堆排序演算法 Python 堆排序
python 堆排序 堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。堆排序可以說是一種利用堆的概念來排序的選擇排序。largest i l 2 i 1 left 2 i...
排序演算法之堆排序
前言 今天我來介紹下堆排序,在寫堆排序 之前,我們要知道堆的概念!堆的定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 當然,這是小根堆,大根堆則換成 號。k i 相當於二叉樹的非葉子結點,k 2i 則...