二项式堆插入java

时间:2013-10-29 18:22:58

标签: java

我在插入二项式堆时遇到问题,当我调用插入1时它会打印(1)然后我插入2它显示(2)而不是(1(2))然后三次显示(3)而不是(3)(1(2))。如果有人能帮我找出问题,我将非常感激。先感谢您。这是我的代码

public class BHeap {

    int key;
    int degree;//The degree(Number of children)
    BHeap parent, leftmostChild, rightmostChild, rightSibling,root,previous,next;
    public BHeap(){
        key =0;
        degree=0;
        parent =null;
        leftmostChild=null;
        rightmostChild=null;
        rightSibling=null;
        root=null;
        previous=null;
        next=null;
    }
    public BHeap merge(BHeap y){
        BHeap newHeap = new BHeap();
        BHeap currentHeap = y;
        BHeap nextHeap = y.rightSibling;
        while(currentHeap.rightSibling !=null){
            if(currentHeap.degree==nextHeap.degree){
                if(currentHeap.key<nextHeap.key){
                    if(currentHeap.degree ==0){
                        currentHeap.leftmostChild=nextHeap;
                        currentHeap.rightmostChild=nextHeap;
                        currentHeap.rightSibling=nextHeap.rightSibling;
                        nextHeap.rightSibling=null;
                        nextHeap.parent=currentHeap;
                        currentHeap.degree++;
                    }
                    else{
                        newHeap = currentHeap;
                        newHeap.rightmostChild.rightSibling=nextHeap;
                        newHeap.rightmostChild=nextHeap;
                        nextHeap.parent=newHeap;
                        newHeap.degree++;
                        nextHeap.rightSibling=null;
                        nextHeap=newHeap.rightSibling;
                    }
                }
                else{
                    if(currentHeap.degree==0){
                        nextHeap.rightmostChild=currentHeap;
                        nextHeap.rightmostChild.root = nextHeap.rightmostChild;//add
                        nextHeap.leftmostChild=currentHeap;
                        nextHeap.leftmostChild.root = nextHeap.leftmostChild;//add
                        currentHeap.parent=nextHeap;
                        currentHeap.rightSibling=null;
                        currentHeap.root=currentHeap;//add
                        nextHeap.degree++;
                    }
                    else{
                        newHeap=nextHeap;
                        newHeap.rightmostChild.rightSibling=currentHeap;
                        newHeap.rightmostChild=currentHeap;
                        currentHeap.parent= newHeap;
                        newHeap.degree++;
                        currentHeap=newHeap.rightSibling;
                        currentHeap.rightSibling=null;
                    }
                }
            }
            else{
                currentHeap=currentHeap.rightSibling;
                nextHeap=nextHeap.rightSibling;
            }
        }
        return y;
    }
    public void Insert(int x){
        BHeap newHeap= new BHeap();
        newHeap.key=x;
        if(this.root==null){
            this.root=newHeap;
        }
        else{
            this.root = merge(newHeap);
        }
    }
    public void Display(){
        System.out.print("(");
        System.out.print(this.root.key);
        if(this.leftmostChild != null){
            this.leftmostChild.Display();
        }
        System.out.print(")");
        if(this.rightSibling!=null){
            this.rightSibling.Display();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

当您插入时,您正在创建一个新的BHeap对象,然后将其传递给merge()。您的新BHeap没有rightSibling,因此您跳过整个while循环,只返回新的BHeap。因此,新的BHeap成为整个root的{​​{1}},你就会丢掉以前的内容。

更新:我不打算编写伪代码,因为它就在你的代码中。

所以你制作了一个新的BHeapBHeap。您的Insert(1)方法会生成第二个新Insert,然后检查当前BHeap的{​​{1}}。那是空的,所以第二个root变为BHeap。没关系。

现在你BHeap。再次,创建另一个root。这次当前Insert(2)的{​​{1}}不为空,因此我们调用BHeap传递新的root。请注意,这个新的BHeap现在被引用(在merge内)为BHeap。另请注意,除了设置BHeap字段以外,您没有对此新merge执行任何操作,因此所有其他字段均为空

y内,你制作了另一个BHeap对象,并制作另一个引用key的引用merge。 (同样,只有BHeap字段已设置,因此所有其他字段都为空。)您将y的currentHeap称为y,然后是key循环。 rightSibling循环表示虽然nextHeap的{​​{1}}不为空,但请执行一些操作。

但正如我上面所说,关于while的所有(又名while又称您在rightSibling中创建的全新currentHeap null 。因此,系统会跳过整个currentHeap循环,并从y返回BHeap

然后

Insert接受来自while的返回值,并将其设置为当前y的{​​{1}}。旧的merge被丢弃,坐在角落里,在垃圾收集器出现之前,在悲伤的命运中痛苦地哭泣,并把它拖入早期的坟墓。新的Insert得意洋洋地欢呼并统治至尊,y的王(以及root的唯一成员)......直到你打电话给BHeap

而你呢?您将学习如何使用调试器。

答案 1 :(得分:1)

在方法merge中,您传递了BHeap个对象y。您确实更改了任何内容,因为您在BHeap方法中创建并传递给merge的{​​{1}}对象不会添加任何兄弟。 while循环永远不会运行。

另外,我们认为您可能希望查看insert方法。您似乎没有考虑到要合并的当前merge,只需重新格式化给定的BHeap参数。