python学习笔记--堆(heap)

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]

当N相对较小的时候,使用堆结构会有更高的效率,这里涉及到两个函数:nlargest和nsmallest,例如:

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]

4.实现优先队列

利用现有的堆操作,能够实现一个简单的优先队列:

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') 


你可能感兴趣的:(python)