堆的实现通过构造二叉堆,实为二叉树的一种;这种数据结构具有以下性质:

  • 任意节点小于(或大于)它的后裔,最小元(或最大元)在堆的根上
  • 堆总是一颗完整树。即除了最低层,其它层的节点都被元素填满,且最低层极可能的从左向右填充。

 

复杂度:

 

 

 

应用:

找出最小或最大的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())