优先队列_heap

定义

在计算机科学领域,堆是指一个特定的基于数结构的数据结构,其必须满足堆属性:

如果A是B的父级节点,那么A和B的排序规则,和整棵数的排序规则一致。也就是说,要么整棵树中父节点都大于或等于字节点,最大的节点是根节点(最大堆);要么整棵树中所有的父节点都小于或者等于子节点,最小的节点是根节点(最小堆)。堆结构在一些有关图的算法中有着重要作用,比如宽度优先遍历的Dijkstra’s algrithm;在堆排序中也起着重要作用。
在这里插入图片描述
一种著名的数据结构是堆(heap),它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。相比于列表方法min,这样做的效率要高得多。
实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块。这个模块名为heapq(其中的q表示队列),它包含6个函数,其中前4个与堆操作直接相关。必须使用列表来表示堆对象本身。

                                                                         模块heapq中一些重要的函数
                                                           函 数                                                           描 述
                                                  heappush(heap, x)                                        将x压入堆中
                                                    heappop(heap)                                      从堆中弹出最小的元素
                                                    heapify(heap)                                           让列表具备堆特征
                                              heapreplace(heap, x)                            弹出最小的元素,并将x压入堆中
                                                  nlargest(n, iter)                                       返回iter中n个最大的元素
                                                    nsmallest(n, iter)                                   返回iter中n个最小的元素

函数heappush用于在堆中添加一个元素。请注意,不能将它用于普通列表,而只能用于使用各种堆函数创建的列表。原因是元素的顺序很重要(虽然元素的排列顺序看起来有点随意,并没有严格地排序)。

from heapq import *
from random import shuffle
data = list(range(10))
shuffle(data)
heap = []
for n in data:
… heappush(heap, n)

heap
[0, 1, 3, 6, 2, 8, 4, 7, 9, 5]

heappush(heap, 0.5)
heap
[0, 0.5, 3, 6, 1, 8, 4, 7, 9, 5, 2]
元素的排列顺序并不像看起来那么随意。它们虽然不是严格排序的,但必须保证一点:位置i处的元素总是大于位置i // 2处的元素(反过来说就是小于位置2 * i和2 * i + 1处的元素)。这是底层堆算法的基础,称为堆特征(heap property)。
函数heappop弹出最小的元素(总是位于索引0处),并确保剩余元素中最小的那个位于索引0处(保持堆特征)。虽然弹出列表中第一个元素的效率通常不是很高,但这不是问题,因为heappop会在幕后做些巧妙的移位操作。

heappop(heap)
0

heappop(heap)
0.5

heappop(heap)
1

heap
[2, 5, 3, 6, 9, 8, 4, 7]
函数heapify通过执行尽可能少的移位操作将列表变成合法的堆(即具备堆特征)。如果你的堆并不是使用heappush创建的,应在使用heappush和heappop之前使用这个函数。

heap = [5, 8, 0, 3, 6, 7, 9, 1, 4, 2]
heapify(heap)
heap
[0, 1, 5, 3, 2, 7, 9, 8, 4, 6]
函数heapreplace用得没有其他函数那么多。它从堆中弹出最小的元素,再压入一个新元素。相比于依次执行函数heappop和heappush,这个函数的效率更高。

heapreplace(heap, 0.5)
0

heap
[0.5, 1, 5, 3, 2, 7, 9, 8, 4, 6]

heapreplace(heap, 10)
0.5

heap
[1, 2, 5, 3, 6, 7, 9, 8, 4, 10]

nlargest(n, iter)和nsmallest(n, iter),:分别用于找出可迭代对象iter中最大和最小的n个元素。这种任务也可通过先排序(如使用函数sorted)再切片来完成,但堆算法的速度更快,使用的内存更少(而且使用起来也更容易)。

在这里插入图片描述

输出结果

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值