對於排序演算法有很多種,其中包括常見的:
氣泡排序,選擇排序, 插入排序, 希爾排序, 快速排序, 歸併排序, 堆排序
這裡主要講一下堆排序, 可以採用自己的方式實現, 也可以採用python內建模組heapq實現, 現在分別從這兩種方法實現一下.
(1) 自己實現
import math
from collections import deque
def print_tree(array): #列印堆排序使用
'''深度 前空格 元素間空格
1 7 0
2 3 7
3 1 3
4 0 1
'''# first=[0]
# first.extend(array)
# array=first
index = 1
depth = math.ceil(math.log2(len(array))) # 因為補0了,不然應該是math.ceil(math.log2(len(array)+1))
sep = ' '
for i in range(depth):
offset = 2 ** i
print(sep * (2 ** (depth - i - 1) - 1), end='')
line = array[index:index + offset]
for j, x in enumerate(line):
print("}".format(x, len(sep)), end='')
interval = 0 if i == 0 else 2 ** (depth - i) - 1
if j < len(line) - 1:
print(sep * interval, end='')
index += offset
print()
def swap_param(l, i, j):
l[i], l[j] = l[j], l[i]
return l
def heap_adjust(l, start, end):
# 調整大頂堆
temp = l[start]
i = start
j = 2 * i # 左孩子節點索引2*i, 右孩子節點索引為2*i+1
while j <= end:
if (j < end) and (l[j] < l[j+1]): # 左右孩子節點比較
j += 1
if temp < l[j]: # 先比較右孩子節點,選出大的和父節點比較
l[i] = l[j] # 和父節點交換
i = j
j = 2 * i
else:
break
l[i] = temp
def heap_sort(l):
'''堆排序,採用大根堆 公升序
'''l_length = len(l) - 1
# 得到初始最大根堆
first_sort_count = l_length // 2 # 最後乙個非葉子節點
for i in range(first_sort_count): # 遍歷每個非葉子節點
heap_adjust(l, first_sort_count - i, l_length)
#print(l)
for i in range(l_length - 1): # 大根堆最大值和最右下節點交換
l = swap_param(l, 1, l_length - i)
heap_adjust(l, 1, l_length - i - 1) # 重新構造大根堆
return [l[i] for i in range(1, len(l))]
if __name__ == '__main__':
#alist = [0, 6, 8, 2, 3, 9, 7, 4, 1, 5, 10]
alist = deque([16, 7, 3, 20, 17, 8])
print(heap_sort(alist))
(2) 採用python,模組實現
對於heapq中的函式有
import heapq as hq
from random import shuffle
data = list(range(10))
shuffle(data)
heap =
for i in data:
print(heap)
print(heap)
print(heap)
元素的排列順序並不像看起來那麼隨意。它們雖然不是嚴格排序的,但必須保證一點:位置i處的元素總是大於位置i // 2處的元素(反過來說就是小於位置2 * i和2 * i + 1處的元素)。這是底層堆演算法的基礎,稱為堆特徵(heap property)。
nlargest(n, iter)和nsmallest(n, iter):分別用於找出可迭代物件iter中最大和最小的n個元素。這種任務也可通過先排序(如使用函式sorted)再切片來完成,但堆演算法的速度更快,使用的記憶體更少(而且使用起來也更容易)。
hq.heapreplace()函式將最小的數彈出之後,再將x壓入堆中
除了上述幾種常見的函式,還有merge()函式,該函式的迭代性質意味著它對所有提供的序列都不會做一次性讀取,因此可以處理非常長的序列,而開銷卻非常小.此外,它要求所有的輸入序列都是有序的,它只是簡單地檢查每個輸入序列中的第乙個元素,將最小的那個傳送出去,然後重複執行此步驟,直到所有的輸入序列都耗盡為止.
內容參考自
Python 標準模組堆heapq詳解
import heapq nums 8,2,23,1,7,4,18,23,42,37,2 heapq.heapify 將list x 轉換成堆,原地,線性時間內。heapq.heapify nums print nums 將 item 的值加入 heap 中,保持堆的不變性。print nums 彈...
python模組之heapq模組(堆)基本操作
1 匯入模組 import heapq 匯入模組2 heapq 提供的常用方法 heapq.heapify head 將陣列轉化成堆 刪除堆頂,也就是最小值 往堆中增元素 heapq.nlargest n,head 查堆中最大的n個數 heapq.nsmallest n,head 查堆中最小的n個數...
Python中的heapq模組
heapq模組提供基於堆的優先排序演算法,內建模組位於.anaconda3 lib heapq.py。堆的邏輯結構就是完全二叉樹,並且二叉樹中父節點的值小於等於該節點的所有子節點的值。這種實現可以使用 heap k heap 2k 1 並且 heap k heap 2k 2 其中 k 為索引,從 0...