heapq内置模块位于./Anaconda3/Lib/heapq.py,提供基于堆的优先排序算法
堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值。这种实现可以使用 heap[k] <= heap[2k+1] 并且 heap[k] <= heap[2k+2] (其中 k 为索引,从 0 开始计数)的形式体现,对于堆来说,最小元素即为根元素 heap[0]。
1.初始化
可以通过 list 对 heap 进行初始化,或者通过 api 中的 heapify 将已知的 list 转化为 heap 对象。
2. heapq.py中提供的函数方法
heapq.heappush(heap, item)
heapq.heappop(heap):返回 root 节点,即 heap 中最小的元素。
heapq.heapreplace(heap,item): python3中heappushpop的更高效版。
heapq.heappushpop(heap, item):向 heap 中加入 item 元素,并返回 heap 中最小元素。
heapq.heapify(x):Transform list into a heap, in-place, in O(len(x)) time
heapq.merge(*iterables, key=None, reverse=False)
heapq.nlargest(n, iterable, key=None):返回可枚举对象中的 n 个最大值,并返回一个结果集 list,key 为对该结果集的操作。
heapq.nsmallest(n, iterable, key=None):同上相反
heapq._heappop_max(heap): Maxheap version of a heappop
heapq._heapreplace_max(heap,item):Maxheap version of a heappop followed by a heappush.
heapq._heapify_max(x):Transform list into a maxheap, in-place, in O(len(x)) time
heapq._siftdown(heap,startpos,pos): Follow the path to the root, moving parents down until finding a place
heapq._siftup(heap,pos):Bubble up the smaller child until hitting a leaf
heapq._siftdown_max(heap,startpos,pos):Maxheap variant of _siftdown
heapq._siftup_max(heap,pos):Maxheap variant of _siftup
3. 举例
1 import heapq 2 def heapsort(iterable): 3 h = [] 4 for i in iterable: 5 heapq.heappush(h, i) 6 return [heapq.heappop(h) for i in range(len(h))] 7 8 # method 1: sort to list 9 s = [3, 5, 1, 2, 4, 6, 0, 1] 10 print(heapsort(s)) 11 ''' 12 [0, 1, 1, 2, 3, 4, 5, 6] 13 ''' 14 15 # method 2: use key to find price_min 16 portfolio = [{'name': 'IBM', 'shares': 100, 'price': 91.1}, 17 {'name': 'AAPL', 'shares': 50, 'price': 543.22}, 18 {'name': 'FB', 'shares': 200, 'price': 21.09}, 19 {'name': 'HPQ', 'shares': 35, 'price': 31.75}, 20 {'name': 'YHOO', 'shares': 45, 'price': 16.35}, 21 {'name': 'ACME', 'shares': 75, 'price': 115.65}] 22 cheap = heapq.nsmallest(1, portfolio, key=lambda s:s['price']) 23 print(cheap) 24 ''' 25 [{'name': 'YHOO', 'shares': 45, 'price': 16.35}] 26 ''' 27 28 # method 3: use while to push min element 29 def heapilize_list(x): 30 n = len(x) 31 # 获取存在子节点的节点 index 列表,并对每个节点单元进行最小堆处理 32 for i in reversed(range(n // 2)): 33 raiseup_node(x, i) 34 35 def put_down_node(heap, startpos, pos): 36 current_item = heap[pos] 37 # 判断单元中最小子节点与父节点的大小 38 while pos > startpos: 39 parent_pos = (pos - 1) >> 1 40 parent_item = heap[parent_pos] 41 if current_item < parent_item: 42 heap[pos] = parent_item 43 pos = parent_pos 44 continue 45 break 46 heap[pos] = current_item 47 48 def raiseup_node(heap, pos): 49 heap_len = len(heap) 50 start_pos = pos 51 current_item = heap[pos] 52 left_child_pos = pos * 2 + 1 53 while left_child_pos < heap_len: 54 right_child_pos = left_child_pos + 1 55 # 将这个单元中的最小子节点元素与父节点元素进行位置调换 56 if right_child_pos < heap_len and not heap[left_child_pos] < heap[right_child_pos]: 57 left_child_pos = right_child_pos 58 heap[pos] = heap[left_child_pos] 59 pos = left_child_pos 60 left_child_pos = pos * 2 + 1 61 heap[pos] = current_item 62 put_down_node(heap, start_pos, pos) 63 64 p = [4, 6, 2, 10, 1] 65 heapilize_list(p) 66 print(p) 67 ''' 68 [1, 4, 2, 10, 6] 69 '''