Python中堆模組heapq

2021-09-25 14:54:12 字數 3220 閱讀 2739

對於排序演算法有很多種,其中包括常見的:

氣泡排序,選擇排序, 插入排序, 希爾排序, 快速排序, 歸併排序, 堆排序

這裡主要講一下堆排序, 可以採用自己的方式實現, 也可以採用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...