-1

Everytime I add a new node into the tree first it sorts it as a binary tree then recursively look up for violations in AVL.

The problem is in my rotate function I tried to test for the AVL violation which requires a left-left rotation and when I do that by first creating a root, then creating a right child a and then another left child b of a. Now what happens is that it outputs got til the end then I get an error saying:

Exception in thread "main" java.lang.StackOverflowError

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

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

I really don't understand the problem

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");
            }
        }
Sachith Muhandiram
  • 2,819
  • 10
  • 45
  • 94
mouse_s
  • 58
  • 1
  • 9

3 Answers3

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

this recursive method has no exit when left is not null it will invoke left.height() left.height() left.height() left.height()........ until stack overflow

nail fei
  • 2,179
  • 3
  • 16
  • 36
  • how do you suggest exiting the method? – mouse_s Nov 28 '16 at 02:07
  • My idea is that if we need to calculate the height of **node** then calculate the height of its left child and right child thenreturn 1 + Math.max(leftHeight, rightHeight); the complete code can be this: '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);
    }'
    – nail fei Nov 28 '16 at 02:14
  • Presumably height is a method belonging to AVLNode, in which case the recursive calls should terminate eventually, assuming a proper tree structure. Though this is the method where the overflow occurs, it's not the cause of the problem. – Lidae Nov 28 '16 at 02:21
  • @ Lidae I dont think so. If left is not null, it will recursive invoke left.height() , the left its **itself** rather than its left child. So it wont exit. – nail fei Nov 28 '16 at 02:27
  • @cainiaofei I'm inferring from the rest of the code, but it seems like each AVLNode contains another AVLNode called "left". So the recursion would become node.height()->node.left.height()->node.left.left.height() etc. If it the structure is a tree, there would be no loops and the method eventually terminates. – Lidae Nov 28 '16 at 02:32
0

I think you have a problem with the rotate method, though it's hard to debug just by reading the code. It seems to me you are getting a cyclic reference which then causes the StackOverflow in the height method. Though height is where the overflow occurs according to the stack trace, it shouldn't happen unless there are cycles in the tree structure. If one of the nodes has itself as a left child, for example, this would happen.

I'm not really familiar with the AVL algorithm, but it looks to me like one source of error (possibly not the only one) in your rotate method is that parent's left child might get set to test's right child, but test's right child's parent is never set to parent.

Again, it's pretty hard to read and debug the code like this. A suggestion is to try to divide the algorithm into smaller chunks, or make small helper functions that are easy to verify.

Lidae
  • 288
  • 2
  • 7
  • you're right I really rushed through with the rotation method I'll work on making it much clearer – mouse_s Nov 28 '16 at 02:25
0

My idea is that if we need to calculate the height of node then calculate the height of its left child and right child then
return 1 + Math.max(leftHeight, rightHeight)
the complete code can be this:

  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);
  }
nail fei
  • 2,179
  • 3
  • 16
  • 36