1.heapq模块
heapq模块中提供了一系列的堆(默认小根堆)操作,下面给出一些常用的方法:
nums=[20, 38, 100, 50, 94, 22, 35, 38, 0, 80, 90, 69, 37]
heap=[] # 建立空堆 由于堆是一个完全二叉树,完全二叉树的结点编号与列表下标存在一一对应的关系,因此本质上是一个列表
for i in range(len(nums)):
heapq.heappush(heap,nums[i]) # 向堆中插入元素
print(heap) # [0, 20, 22, 38, 80, 37, 35, 50, 38, 94, 90, 100, 69]
print(heap[0]) # 0 堆顶元素
print(heapq.heappop(heap)) # 0 堆顶元素弹出
heapq.heappushpop(heap,999) # 弹出堆顶元素,同时向heap中插入新的元素,较分开完成(heappop+heappush)更为高效
print(heap) # [22, 38, 35, 38, 80, 37, 999, 50, 69, 94, 90, 100]
heapq.heapify(nums) # 将列表调整为堆 时间复杂度O(n)
print(nums) # [0, 20, 22, 38, 80, 37, 35, 38, 50, 94, 90, 69, 100]
2.堆排序算法
利用heapq中的一些方法,可以很容易地完成堆排序:
def heapsort(seq):
res=[]
heap = list(seq)
heapq.heapify(heap)
while len(heap) != 0:
res.append (heapq.heappop(heap))
return res
print(heapsort(nums)) # [0, 20, 22, 35, 37, 38, 38, 50, 69, 80, 90, 94, 100]
3.寻找序列中最大或最小的N个元素
当N=1时,直接使用min(seq)或者max(seq)返回最小或者最大值
当N与集合大小相当,采用排序+切片的方法更为妥当,例如:
lista = [64, 92, 93, 83, 85, 50, 10, 49, 28, 60]
N = 7
listb = sorted(lista)
print(listb[0:N], listb[-1:-1 - N:-1]) # [10, 28, 49, 50, 60, 64, 83] [93, 92, 85, 83, 64, 60, 50]
lista = [64, 92, 93, 83, 85, 50, 10, 49, 28, 60]
print(heapq.nlargest(3, lista)) # [93, 92, 85]
print(heapq.nsmallest(3, lista)) # [10, 28, 49]
利用现有的堆操作,能够实现一个简单的优先队列:
import heapq
class priorityQueue:
def __init__(self):
self._queue=[]
def push(self,item,priority):
heapq.heappush(self._queue,(-priority,item))
def pop(self):
return heapq.heappop(self._queue)
def isempty(self):
return len(self._queue)==0
pq=priorityQueue()
pq.push('zhangsan',1)
pq.push('lisi',3)
pq.push('wangwu',2)
while pq.isempty()==False:
print(pq.pop(),end=' ') # (-3, 'lisi') (-2, 'wangwu') (-1, 'zhangsan')