Python排序演算法之堆排序

2021-09-27 12:38:43 字數 2246 閱讀 3067

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 則...