【问题标题】:How to implement decrease-key in a Fibonacci heap to run in O(1) amortized time?如何在斐波那契堆中实现减少键以在 O(1) 摊销时间内运行?
【发布时间】:2013-10-30 22:49:54
【问题描述】:

如何在斐波那契堆上的递减键操作中获得 O(1) 的摊销复杂度?使用 BFS 仅在 Fibonacci 堆中找到包含该元素的节点需要 O(n) 时间,这应该使得不可能获得 O(1) 摊销时间。

作为参考,这是我搜索相关节点的 BFS 实现:

   public fHeapNode search(int x){
       Stack<fHeapNode> stack = new Stack<fHeapNode>();
        stack.push(minNode);

        //Breath first searching
        while (!stack.empty()) {
            fHeapNode curr = stack.pop();

            if(curr.data==x) {return curr;}

            else{
                if (curr.child != null) {
                    stack.push(curr.child);
                }
                fHeapNode start = curr;
                curr = curr.right;

                while (curr != start) {

                    if (curr.child != null) {
                        stack.push(curr.child);
                    }
                    if(curr.data==x) {return curr;}
                    curr = curr.right;
                }

            }
        }  


        return null;


   }

这是我的减少键代码:

       public void decreaseKey(fHeapNode x, double k)
    {
        if (k > x.key) {
        //throw new IllegalArgumentException("entered value is wrong");
        }
        x.key = k;

        fHeapNode tempParent = x.parent;

        if ((tempParent != null) && (x.key < tempParent.key)) {
            cut(x,tempParent);
            cascadingCut(tempParent);
        }

        if (x.key < minNode.key) {
            minNode = x;
        }
    }

【问题讨论】:

    标签: java big-o prims-algorithm fibonacci-heap decrease-key


    【解决方案1】:

    通常,在实现斐波那契堆时,您的 enqueue 实现将返回一个指向新插入节点的指针。这样,您可以存储指针以供以后使用。如果你没有指向它的指针,你必须花费 O(n) 时间搜索节点,这是绝对正确的。

    例如,这里是my own personal implementation of a Fibonacci heapenqueue方法在这里给出:

    public Entry<T> enqueue(T value, double priority) {
         // ...
    }
    

    注意它如何返回代表该节点的Entry&lt;T&gt;decreaseKey对应的实现有这个接口:

    public void decreaseKey(Entry<T> entry, double newPriority) {
         // ...
    }
    

    这里的参数是Entry&lt;T&gt;,对应的节点持有应该减少key的元素。如果没有enqueue 返回的Entry&lt;T&gt;,则无法调用此方法,否则无法有效实现。

    希望这会有所帮助!

    【讨论】:

    • 我可以通过创建一个头节点数组列表来做到这一点吗?所以更新发生它也会自动反映在数组列表中,因为它们只是参考?我说的对吗??
    • 在实现 Prim 算法时,存储一个包含所有堆节点的数组很常见,这正是您提到的原因。这将大大加快速度。
    • @RohitGarg- 很高兴为您提供帮助!请记住,您始终可以接受此答案以将问题标记为已关闭。 :-)
    猜你喜欢
    • 2011-08-27
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多