堆的实现通过构造二叉堆,实为二叉树的一种;这种数据结构具有以下性质:
- 任意节点小于(或大于)它的后裔,最小元(或最大元)在堆的根上
- 堆总是一颗完整树。即除了最低层,其它层的节点都被元素填满,且最低层极可能的从左向右填充。
复杂度:
应用:
找出最小或最大的n个元素
nlargest 和 nsmallest
from heapq import nlargest, nsamllest nums = [1, 8, 2, 23, 7, -4, 18, 23, 42] print(nlargest(3, nums)) print(nsmallest(3, nums))
这两个函数都可以接受一个key,
portfolio = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22} ] cheap = nsmallest(3, portfolio, key=lambda s: s['price']) expensive = nlargest(3, portfolio, key=lambda s: s['price'])
如果n = 1,使用 min 和 max 更加的快;如果 n 的大小和 序列的长度差不多时,使用 sort 排序,然后切片会更加合适。
创建优先级队列:
import heapq class PriortyQueue: def __init__(self): self._queue = [] self._index = 0 def push(self, item, priorty): heapq.heappush(self._queue, (-priorty, self._index, item)) self._index += 1 def pop(self): return heapq.heappop(self._queue)[-1] class Item: def __init__(self, name): self.name = name def __repr__(self): return f'Item({self.name!r})' q = PriortyQueue() q.push(Item('foo'), 1) q.push(Item('bar'), 2) q.push(Item('spam'), 3) print(q.pop())