heapq源码解读(三)

Python heapq源码解读计划(三)

本文是解读heapq的第三节,主要来讲解一下heappopheappushheappushpopheapreplace这四个个函数的具体实现。

heappop函数的实现

heappop这个函数的具体作用为将heap内的最小值pop掉,并且返回这个最小值,与此同时这个heap还是保持在最小堆的状态。

首先,heapq的堆使用list来实现的,所以list可以执行的操作在这里也是可以使用的。

lastelt = heap.pop()

所以heappop的源码会使用pop这个函数,先将一个值给踢掉。这个时候要保存住这个pop的值。如果pop完了这个heap为空了,那么直接返回pop的值即可。如果pop掉值后heap不为空,那么之前pop的值并不是heap中的最小值,所以需要将这个pop的值换为最小的值,也就是heap[0]。因为之前pop的值并不确定是否为剩余值中的最小值,所以使用_siftup(heap,0)来对这个heap进行一次调整。使其依旧为一个小根堆。

_siftup()的解读具体要看heapq源码解读计划(二)

这部分的代码实现如下:

    if heap:
        returnitem = heap[0]
        heap[0] = lastelt
        heapq._siftup(heap, 0)
        return returnitem

整体的代码实现如下:

def heappop(heap):
    """Pop the smallest item off the heap, maintaining the heap invariant."""
    lastelt = heap.pop()    # raises appropriate IndexError if heap is empty
    if heap:
        returnitem = heap[0]
        heap[0] = lastelt
        _siftup(heap, 0)
        return returnitem
    return lastelt

heappush函数的实现

heappush(heap,x)这个函数的主要作用为将x的值添加到heap中去,并将heap保持在一个小根堆的状态。将x添加到heap中用到的是list的append的方法:

heap.append(item)

然后使用_siftdown函数来将新append进去的值来与前面的叶节点值进行比较,如果比之前的值小,则进行一个交换,否则就会停止交换。

整体的heappush实现如下:

def heappush(heap, item):
    """Push item onto heap, maintaining the heap invariant."""
    heap.append(item)
    _siftdown(heap, 0, len(heap)-1)

heapreplace函数的实现

函数英文描述如下:

Pop and return the current smallest value, and add the new item.

具体来说就是先将最小值pop掉,然后再添加进去新值,最后要保持heap处于一个小根堆的状态。

heapreplace(heap,x)函数实现的功能为先将x的值和heap中的最小值进行一个交换,然后保持

具体的实现为先将heap[0]的值赋给returnitem,然后再将x的值赋给heap[0]。然后因为这是将值添加在了头部,所以是要用_siftup来对数组进行一个处理。最后将returnitem返回即可。

heapreplace的源码如下:

def heapreplace(heap, item):
    returnitem = heap[0]    # raises appropriate IndexError if heap is empty
    heap[0] = item
    _siftup(heap, 0)
    return returnitem

heappushpop函数的实现

heappushpop(heap,x)函数实现的是先将x的值添加到heap中去,然后再pop掉堆中最小的值。

如果heap是空的,或是heap[0]的值大于x的值,那么无需处理,直接将x的值pop掉即可。在代码上的实现为判断一下,如果是上述情况的话,heap无需处理,直接将x的值返回即可。

如果heap[0]的值小于x的值,那么将x的值和heap[0]的值进行互换,然后_siftup一下即可。

具体代码实现:

def heappushpop(heap, item):
    if heap and heap[0] < item:
        item, heap[0] = heap[0], item
        _siftup(heap, 0)
    return item
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌小奇0639

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值