python基础之heapq模块(堆模块)

堆是一种数据结构,本质上是一种二叉树。在python中可以使用heapq模块实现,heapq可以实现一个简单的优先级队列。
一、堆的性质
堆分为小根堆与大根堆,小根堆的第一个元素可以理解为数值最小的元素,大根堆则相反,以下以小根堆为例
在这里插入图片描述
上图的小根堆序列 [A,B,C,D,E,F,G] 中,根节点A为最小值。
在堆的插入和删除过程中,小根堆要保持其性质,即父节点的值要小于或等于其子节点的值,其值就是该数据的优先级
二、堆的方法
1、创建堆—heappush(heap, item)`

2、弹出并返回堆中最小的元素—heapq.heappop(heap)
【注】在弹出最小元素后,堆队列性质保持不变。使用heap[0]可以访问最小元素而不删除它

3、将item压入堆中,并弹出其最小元素
—heapq.heappushpop(heap, item)
【注】相当于调用 heappush() 再调用 heappop() ,但是比它们更有效率

4、将列表转换成堆—heapq.heapify(x)

5、弹出并返回 heap 中最小的一项,同时压入新的 item—heapq.heapreplace(heap, item)
【注】相当于调用 heappop() 再调用 heappush() ,但是比它们更有效率

6、将多个已排序的输入合并为一个已排序的输出
heapq.merge(iterables, key=None, reverse=False)
【注】*iterables为多个已排序的输入,key为None时,直接比较元素的大小,reverse=True逆序排列

7、返回前n个最大元素组成的列表—heapq.nlargest(n, iterable, key=None)

8、返回前n个最小元素组成的列表—heapq.nsmallest(n, iterable, key=None)

代码示例:

import heapq
lst = [8, 2, 6, 1, 5, 3, 9, 11]
#建立空堆
hq = []
#将元素压入堆中
for i in lst:
    heapq.heappush(hq, i)
print(hq)
#[1, 2, 3, 8, 5, 6, 9, 11]

#弹出堆顶元素
a = heapq.heappop(hq)
print(a)
print(hq)
#1
#[2, 5, 3, 8, 11, 6, 9]

#将item压入堆中,并弹出其最小元素
b = heapq.heappushpop(hq, 0)
print(b)
print(hq)
#0
#[2, 5, 3, 8, 11, 6, 9]

#弹出并返回 heap 中最小的一项,同时压入新的 item
c = heapq.heapreplace(hq, 0)
print(c)
print(hq)
#2
#[0, 5, 3, 8, 11, 6, 9]

#将多个已排序的输入合并为一个已排序的输出
d = [0, 1, 3, 5]
e = [2, 6, 8, 9]
print(list(heapq.merge(d,e)))
#[0, 1, 2, 3, 5, 6, 8, 9]

#返回前n个最大元素组成的列表
f = heapq.nlargest(3, hq)
print(f)
#[11, 9, 8]

#返回前n个最小元素组成的列表
g = heapq.nsmallest(3, hq)
print(g)
#[0, 3, 5]

#将列表转换成堆
heapq.heapify(lst)
print(lst)
#[1, 2, 3, 8, 5, 6, 9, 11]

三、优先级队列
堆能够很方便的实现优先级排序
用priority表示每组数据的优先级,堆元素使用元组方便比较,简单示例如下:

hq = []
#数据使用(priority, data)表示
heapq.heappush(hq, (5,"apple"))
heapq.heappush(hq, (3,"orange"))
heapq.heappush(hq, (6,"strawberry"))
heapq.heappush(hq, (0,"banana"))
print(heapq.heappop(hq))
#(0, 'banana')
#0代表其优先级,此时数值越小优先级越高

上面是一种很简单的优先级排序,较复杂的情况是可能会出现优先级相同的情况,此时可以通过如下的方式解决

import itertools
#产生一个从0开始的序列
counter = itertools.count()
hq = []
#建立元组(priority, next(counter), data )
#当priority一致时,就比较next(counter)
heapq.heappush(hq, (2, next(counter), "bob"))
heapq.heappush(hq, (5, next(counter), "lucy"))
heapq.heappush(hq, (3, next(counter), "lily"))
heapq.heappush(hq, (6, next(counter), "tom"))
heapq.heappush(hq, (7, next(counter), "jim"))
heapq.heappush(hq, (0, next(counter), "lala"))
heapq.heappush(hq, (2, next(counter), "kuke"))
heapq.heappush(hq, (1, next(counter), "sherly"))
heapq.heappush(hq, (9, next(counter), "blues"))
print(heapq.heappop(hq))
print(heapq.heappop(hq))
print(heapq.heappop(hq))
print(heapq.heappop(hq))
"""
(0, 5, 'lala')
(1, 7, 'sherly')
(2, 0, 'bob')
(2, 6, 'kuke')
"""


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值