heapq源码解读(二)

本文详细分析了Python heapq模块中的heapify函数,该函数用于将列表转换成堆结构。通过_siftup函数,从后向前遍历并调整节点,确保堆属性。接着,_siftdown函数自底向上检查并调整节点,保证堆的性质。整个过程在O(len(x))时间内完成,是heapq模块的关键操作之一。
摘要由CSDN通过智能技术生成

Python heapq源码解读计划(二)

本文为解读heapq部分的第二节,主要是探索heapq中的heapify()函数具体是如何实现的。

前言

首先来回顾一下,heapq中的heap是如何构造的。python heapq的heap使用数组实现,从0开始计数。对于所有的k,
都有 heap[k] <= heap[2 * k+1] 和 heap[k] <= heap[2 * k + 2]。

源码解读

heapify(x)

源码:

def heapify(x):
    """Transform list into a heap, in-place, in O(len(x)) time."""
    n = len(x)
    for i in reversed(range(n//2)):
        _siftup(x, i)

heapify的源码其实很简单:

  • 拿到数组的长度 n

  • 取数组的中位数,然后从后往前遍历运行_siftup(x, i)

_siftup(heap,pos)

源码:

def _siftup(heap, pos):
    endpos = len(heap)
    startpos = pos
    newitem = heap[pos]
    # Bubble up the smaller child until hitting a leaf.
    childpos = 2*pos + 1    # leftmost child position
    while childpos < endpos:
        # Set childpos to index of smaller child.
        rightpos = childpos + 1
        if rightpos < endpos and not heap[childpos] < heap[rightpos]:
            childpos = rightpos
        # Move the smaller child up.
        heap[pos] = heap[childpos]
        pos = childpos
        childpos = 2*pos + 1
    # The leaf at pos is empty now.  Put newitem there, and bubble it up
    # to its final resting place (by sifting its parents down).
    heap[pos] = newitem
    _siftdown(heap, startpos, pos)

_siftup这个函数的作用为,将父节点的值和子节点中较小的节点进行交换,一直到没有子节点。子节点指的是heap[2k + 1] 和heap[2k + 2]。

然后执行_siftdown操作。

_siftdown(heap,startpos,pos)

源码:

def _siftdown(heap, startpos, pos):
    newitem = heap[pos]
    # Follow the path to the root, moving parents down until finding a place
    # newitem fits.
    while pos > startpos:
        parentpos = (pos - 1) >> 1
        parent = heap[parentpos]
        if newitem < parent:
            heap[pos] = parent
            pos = parentpos
            continue
        break
    heap[pos] = newitem

_siftdown作用就是从pos一直向上,如果节点值小于父节点,则进行交换,否则则break掉循环,终止执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

萌小奇0639

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

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

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

打赏作者

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

抵扣说明:

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

余额充值