python学习笔记--堆(heap)

来源:互联网 发布:芈月怎么玩 知乎 编辑:程序博客网 时间:2024/05/16 17:40

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 resprint(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 = 7listb = 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 heapqclass 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)==0pq=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') 


原创粉丝点击