Python-堆结构(heapq)

1.创建堆

创建堆的方式分为两种:一种是先创建一个空的堆,然后再用heapqpush()往堆中添加元素;另一种是将列表转换为堆,用heapqfy()方法。

import heapq

dig = [7,2,9,12,5,3]
# 法1
heap = []
for item in dig:
	heapqpush(heap, item)
# 法2
heap = heapify(dig)

print(heap[0])  # 输出最小元素
res = [heap.heapqpop() for _ in range(len(dig))]
# out: 2
# out: [2,3,5,7,9,12]

heapq 模块还有一个heapq.merge(*iterables) 方法,用于合并多个排序后的序列成一个排序后的序列, 返回排序后的值的迭代器。类似于sorted(itertools.chain(*iterables)),但返回的是可迭代的。

num1 = [32, 3, 5, 34, 54, 23, 132]
num2 = [23, 2, 12, 656, 324, 23, 54]
num1 = sorted(num1)
num2 = sorted(num2)

res = heapq.merge(num1, num2)
print(list(res))

2.访问堆内容

堆创建好后,可以通过`heapq.heappop() 函数弹出堆中最小值。如果需要删除堆中最小元素并加入一个元素,可以使用heapq.heaprepalce() 函数。

heapq.heapreplace(nums, 23)

如果需要获取堆中最大或最小的范围值,则可以使用heapq.nlargest() 或heapq.nsmallest() 函数。

nums = [1, 3, 4, 5, 2]
print(heapq.nlargest(3, nums))
print(heapq.nsmallest(3, nums))
"""
输出:
[5, 4, 3]
[1, 2, 3]
"""

这两个函数还接受一个key参数,用于dict或其他数据结构类型使用。

import heapq
from pprint import pprint
portfolio = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
pprint(cheap)
pprint(expensive)

"""
输出:
[{'name': 'YHOO', 'price': 16.35, 'shares': 45},
 {'name': 'FB', 'price': 21.09, 'shares': 200},
 {'name': 'HPQ', 'price': 31.75, 'shares': 35}]
[{'name': 'AAPL', 'price': 543.22, 'shares': 50},
 {'name': 'ACME', 'price': 115.65, 'shares': 75},
 {'name': 'IBM', 'price': 91.1, 'shares': 100}]
"""

3.heapq应用

3.1 堆排序

该算法和sorted(iterable) 类似,但是它是不稳定的。

def heapsort(iterable):
	h = []
	for value in iterable:
        heappush(h, value)
    return [heappop(h) for i in range(len(h))]
# 输出排序后的iterable
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值