尝试实现AVL树的旋转时获取堆栈溢出

时间:2016-11-28 01:25:55

标签: java avl-tree

每次我首先在树中添加一个新节点,然后将其作为二叉树进行排序,然后以递归方式查找AVL中的违规行为。

问题在于我的旋转功能我试图测试AVL违规,这需要左左旋转,当我这样做时首先创建一个根,然后创建一个右子a,然后另一个左子b 。现在发生的是它的输出直到结束然后我得到一个错误说:

  

Exception in thread "main" java.lang.StackOverflowError

     
    

at AVLTree$AVLNode.height(AVLTree.java:63)

         

at AVLTree$AVLNode.height(AVLTree.java:62)

  

我真的不明白这个问题

54 int getBalance(){
55       int leftHeight = (left == null)?0:left.height();
56       int rightHeight = (right == null)?0:right.height();
57       
58       return leftHeight - rightHeight;
59   }
61 int height(){
62      int leftHeight = (left == null)?0:left.height();
63      int rightHeight = (right == null)?0:right.height();

        return 1 + Math.max(leftHeight, rightHeight);
    }    

public void rotate(AVLNode test){
        System.out.println(test.getBalance());
        if(Math.abs(test.getBalance()) < 2){

            if(test.getParent() != null){
                rotate(test.getParent());
            }
            else{
                return;
            }
        }
        if(test.getBalance() <= -2){

            System.out.println(test.getBalance());

            if(test.getRight().getBalance() <= 0){

                System.out.println("i'm in");
                AVLNode parent = test.getParent();

                if(parent != null){

                    if(parent.getLeft() == test){
                        parent.setLeft(test.getRight());
                    }
                    else{
                        parent.setRight(test.getRight());
                    }
                }

                else{
                    this.root = test.getRight();
                }
                test.setParent(test.getRight());

                if(test.getRight().getLeft() != null){

                test.getRight().getLeft().setParent(test);
                test.setRight(test.getRight().getLeft());
                }

                test.getParent().setLeft(test);
                System.out.println("got till the end");
            }
        }

3 个答案:

答案 0 :(得分:0)

  int height(){
      int leftHeight = (left == null)?0:left.height();
      int rightHeight = (right == null)?0:right.height();
      return 1 + Math.max(leftHeight, rightHeight);
  }

recursive method不是exit时,left没有null它会调用 left.height()left.height()left.height() left.height()........直到堆栈溢出

答案 1 :(得分:0)

我认为你的rotate方法存在问题,但只是通过阅读代码很难调试。在我看来,你得到一个循环引用,然后导致height方法中的StackOverflow。虽然height是根据堆栈跟踪发生溢出的地方,但除非树结构中存在循环,否则不应发生溢出。例如,如果其中一个节点将自己作为左子节点,则会发生这种情况。

我对AVL算法并不是很熟悉,但我认为rotate方法中的一个错误来源(可能不是唯一一个)就是parent左边的孩子可能会设置为test的正确子项,但测试的右子项的父项永远不会设置为parent

同样,很难像这样阅读和调试代码。建议尝试将算法划分为更小的块,或者制作易于验证的小辅​​助函数。

答案 2 :(得分:0)

我的想法是,如果我们需要计算节点的高度,那么计算其左子项和右项的高度然后
return 1 + Math.max(leftHeight, rightHeight)
完整的代码可以是:

  int height(TreeNode tn){ 
      if(tn==null){return 0;}
      int leftHeight = tn.left.height();
      int rightHeight = tn.right.height();
      return 1 + Math.max(leftHeight, rightHeight);
  }