python中heapq堆的讲解

目录

堆结题的基本技巧:

heapq堆的常用方法:

heapq.heappush(heap, item)

heapq.heapify(list)

heapq.heappop(heap)

heapq.heapreplace(heap.item)

heapq.heappushpop(list, item)

heapq.merge(…)

heapq.nlargest(n,heap)

heapq.nsmallest(n,heap)

扫描二维码关注公众号,回复: 12899832 查看本文章

使用heapq编写优先级队列

堆是非线性的树形的数据结构,有两种堆,最大堆与最小堆。( heapq库中的堆默认是最小堆)

最大堆,树种各个父节点的值总是大于或等于任何一个子节点的值。

最小堆,树种各个父节点的值总是小于或等于任何一个子节点的值。

我们一般使用二叉堆来实现优先级队列,它的内部调整算法复杂度为logN。

堆是一个二叉树,其中最小堆每个父节点的值都小于或等于其所有子节点的值。

整个最小堆的最小元素总是位于二叉树的根节点。

python的heapq模块提供了对堆的支持。 heapq堆数据结构最重要的特征是heap[0]永远是最小的元素

堆结题的基本技巧:
常用方法:nlargest(),nsmallest(),heapify(),heappop()

如果需要的个数较小,使用nlargest或者nsmallest比较好

如果需要的个数已经接近了序列长度,使用sorted()[:N]获取前N个数据比较好

如果只需要唯一一个最大或最小值,则直接使用max()或者min()

heapq堆的常用方法:

heapq.heappush(heap, item)
heap为定义堆,item增加的元素

import heapq
h = []
heapq.heappush(h,2)
h
[2]

heapq.heapify(list)
将列表转换为堆

list = [1,2,3,5,1,5,8,9,6]
heapq.heapify(list)
list
[1, 1, 3, 5, 2, 5, 8, 9, 6]

heapq.heappop(heap)
删除并返回最小值,因为堆的特征是heap[0]永远是最小的元素,所以一般都是删除第一个元素。

list
[1, 1, 3, 5, 2, 5, 8, 9, 6]

heapq.heappop(list)
1

list
[1, 2, 3, 5, 6, 5, 8, 9]

heapq.heapreplace(heap.item)
删除并返回最小元素值,添加新的元素值

list = [1, 2, 3, 4, 5, 6, 5, 8, 9]
heapq.heapreplace(list,99)
1

list
[2, 4, 3, 8, 5, 6, 5, 99, 9]

heapq.heappushpop(list, item)
判断添加元素值与堆的第一个元素值对比;如果大,则删除并返回第一个元素,然后添加新元素值item.

                                                                 如果小,则返回item.  原堆不变。

list = [2, 4, 3, 8, 5, 6, 5, 99, 9]
heapq.heappushpop(list,6)
2

list
[3, 4, 5, 8, 5, 6, 6, 99, 9]

heapq.heappushpop(list,1)
1

list
[3, 4, 5, 8, 5, 6, 6, 99, 9]

heapq.merge(…)
将多个堆合并

h = [1000]
for i in heapq.merge(h,list):
print(i,end=" ")
3 4 5 8 5 6 6 99 9 1000

heapq.nlargest(n,heap)
查询堆中的最大n个元素

list
[3, 5, 5, 9, 6, 6, 8, 99]

heapq.nlargest(3,list)
[99, 9, 8]

heapq.nsmallest(n,heap)
查询堆中的最小n个元素

list
[3, 5, 5, 9, 6, 6, 8, 99]

heapq.nsmallest(3,list)
[3, 5, 5]

使用heapq编写优先级队列
class PriorityQueue:
def init(self):
self.__queue = []
self.__index = 0

def push(self, item, priority):
    heapq.heappush(self.__queue, (-priority, self.__index, item))
    # 第一个参数:添加进的目标序列
    # 第二个参数:将一个元组作为整体添加进序列,目的是为了方便比较
    # 在priority相等的情况下,比较_index
    # priority为负数使得添加时按照优先级从大到小排序,因为堆排序的序列的第一个元素永远是最小的
    self.__index += 1
    
def pop(self):
    # 返回按照-priority 和 _index 排序后的第一个元素(是一个元组)的最后一个元素(item)
    return heapq.heappop(self.__queue)[-1]

q = PriorityQueue()
q.push(“bar”, 2)
q.push(“foo”, 1)
q.push(“gork”, 3)
q.push(“new”, 1)
print(q.pop())
print(q.pop())
print(q.pop())
print(q.pop())

“”"
gork # 优先级最高
bar # 优先级第二
foo # 优先级与new相同,比较index,因为先加入,index比new小,所以排在前面
new
“”"

原文链接:https://blog.csdn.net/qq_35883464/article/details/99410423

猜你喜欢

转载自blog.csdn.net/qq_15821487/article/details/114903859
今日推荐