斐波那契堆python实现——Fibonacci Heaps

本文详细介绍了斐波那契堆的Python实现,重点讲解了级联切割和删除操作的高效处理。斐波那契堆作为懒惰二项堆的扩展,提供了更优的decreaseKey和delete性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fibonacci Heaps——python实现

前言

Fibonacci Heaps的所有内容都在这里 Fibonacci Heaps 可以找到。

简单的概括,斐波那契堆其实是 lazy binomial heaps 的扩展,支持更高效的 decreaseKey(v,k)delete(v). 那么在 lazy binomial heaps实现 的基础上稍作改动和扩展即可。

完整代码和测试代码已上传资源…

functions

大部分操作的实现与 lazy binomial heaps 无异。只是一些细节有所不同:在这里 insert(x)    ⟹    \implies insert(v), 插入的是节点,在扩展的 Binomial Tree节点中需要存是否已丢失孩子的 mark,维护 merge 时保证连进来的 root unmarked, 以及 在coalesce step 中创建箱子的个数,log 的 base…

所以大量的重复内容,merge, insert, extractMin, find_min, coalesce step. updateMin,就不在这里展示了,同样参考前面的实现博客吧。

另外表示方法也同之前一样,双向循环链表,父结点只存一个孩子。

representation

decreaseKey(v, k)

这里唯一的问题就是 cascading cut,级联切割,当我们要 decreaseKey 的 node 的父节点已经损失了孩子。此时为了保证 root 的 order 和其节点数 n 的关系 ϕ r o o t . o r d e r ≤ n \phi^{root.order} \leq n ϕroot.ordern,即斐波那契数列的性质,所以也要把 node 的 parent 同样切下来,直到遇到没有损失孩子的 parent 或者根。

    def decreaseKey(self,v,k):
        if k < self.min.data:  # update min ptr
            self.min = v
        v.data = k
        if not v.parent: # root, no need to cut
            return
        new_heap = Fibonacci_Heap()
        if v.pre == v: # only one child
            assert v.parent.order == 1,'wrong order'
            new_heap.head = v
            new_heap.min = v
            self.merge(new_heap)
            v = v.parent
            v.Lchild.parent = None
            v.Lchild = None
        else:
            if v.parent.Lchild == v:
                v.parent.Lchild = v.sibling
            temp = v.parent
            v.pre.sibling = v.sibling
            v.sibling.pre = v.pre
            v.pre = v
            v.sibling = v
            new_heap.head = v
            new_heap.min = v
            self.merge(new_heap)
            v.parent = None
            v = temp
        v.order -= 1
        while v.parent:
            if v.losing_child:
                v.losing_child = False
                if v.pre == v:  # only one child, same as before
                    assert v.parent.order == 1, 'wrong order'
                    new_heap.head = v
                    new_heap.min = v
                    self.merge(new_heap)
                    v = v.parent
                    v.Lchild.parent = None
                    v.Lchild = None
                else:
                    if v.parent.Lchild == v:
                        v.parent.Lchild = v.sibling
                    temp = v.parent
                    v.pre.sibling = v.sibling
                    v.sibling.pre = v.pre
                    v.pre = v
                    v.sibling = v
                    new_heap.head = v
                    new_heap.min = v
                    self.merge(new_heap)
                    v.parent = None
                    v = temp
                v.order -= 1
            else:
                v.losing_child = True
                break

delete(v)

delete(v) 的实现非常简单…

    def delete(self,v):
        self.decreaseKey(v,float('-inf'))
        self.extractMin()

结语

有点儿水…

但堆相关这部分内容,从知识搬运消化,到上码实战,总算完啦,液✌。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值