简体   繁体   中英

AVL Tree Left Rotation

I'm righting an AVL Tree class and I'm having trouble with my "rotateLeft" method. I'm getting a null pointer exception and I'm not sure what's causing it. Here is the class:

public class AVLNode {

// Fields
int data;
AVLNode left;
AVLNode right;
int height;

// Constructors
AVLNode (int data) {
    this(data, null, null);
}

AVLNode (int data, AVLNode left, AVLNode right) {
    this.data = data;
    this.left = left;
    this.right = right;
    this.height = 0;
}


// Returns: new root of this subtree
 public AVLNode insert (int value, AVLNode rt) {
     if (rt == null)
         return new AVLNode(value, null, null);
     if (value < rt.data)
         rt.left = insert(value, rt.left);
     else if (value > rt.data)
         rt.right = insert(value, rt.right);
     // else this is a duplicate, do nothing
     rt.height = Math.max(height(rt.left), height(rt.right)) + 1;
     return balance(rt);
 }

 // Returns : String representation of tree root at this node
 public String toString() {
     return toString(this);
 }

 // Returns : String representation of tree root at rt
 private String toString(AVLNode rt) {
     if (rt == null)
         return "";
     if (rt.left == null && rt.right == null)
         return rt.data + " ";
     String result = rt.data + " ";
     if (rt.left != null)
         result += toString(rt.left);
     if (rt.right != null)
         result += toString(rt.right);
     return result;

}

 // Returns: height of largest subtree, -1 if n is null
 private int height (AVLNode n) {
     return n == null ? -1 : n.height;
 }

 //calculates balance between the nodes
 private int getBalance(AVLNode rt) { 
     if (rt == null) return 0; 
     return height(rt.left) - height(rt.right); 
 }

 // Returns: new root of this subtree after balancing
 private AVLNode balance (AVLNode rt) {
     int bal = getBalance(rt);
     if (rt == null) return rt;

     // Rotate L case
     if (bal > 1 && data < rt.left.data) {
         return rotateRight(rt); 
     }

     // Rotate R case
     if (bal < -1 && data > rt.right.data) {
         return rotateLeft(rt); 
     }

     // Double rotate LR
     if (bal > 1 && data > rt.left.data) {
         return doubleRotateLeftRight(rt);
     } 

     // Double rotate RL
     if (bal < -1 && data < rt.right.data) {
         return doubleRotateRightLeft(rt); 
     }

     return rt;
 }

 // Returns: new root after single rotation of this rt right
 private AVLNode rotateRight(AVLNode rt) {
     //creates new node with the left value of rt as the root
     AVLNode y = rt.left;
     //creates a new node with a null value
     AVLNode rt2 = y.right; 

     // do rotation
     y.right = rt; 
     rt.left = rt2;

     //update height of both nodes
     rt.height = Math.max(height(rt.left), height(rt.right)) + 1;
     y.height =  Math.max(height(y.left), height(y.right)) + 1;

     // Return the new root 
     return y; 
 }

 // Param: AVLNode rt
 // Returns: new root after single rotation of this rt left
 private AVLNode rotateLeft(AVLNode rt) {
     //creates new node with the right values of rt as the root
     AVLNode x = rt.right;
     //creates a new node with a null value
     AVLNode rt2 = x.left; 

     // do rotation
     x.left = rt; 
     rt.right = rt2; 

     //update height of both nodes
     rt.height = Math.max(height(rt.left), height(rt.right)) + 1;
     x.height = Math.max(height(x.left), height(x.right)) + 1;

     // Return the new root 
     return x; 
 }

 private AVLNode doubleRotateLeftRight(AVLNode rt) {
     rt.left = rotateLeft(rt.left);
     rotateRight(rt);
     return rt;
 }

 private AVLNode doubleRotateRightLeft(AVLNode rt) {
     rt.right = rotateRight(rt.right);
     rotateLeft(rt);
     return rt;
 }
}

This is the error specifically:

Exception in thread "main" java.lang.NullPointerException
        at AVLNode.rotateRight(AVLNode.java:118)
        at AVLNode.balance(AVLNode.java:96)
        at AVLNode.insert(AVLNode.java:42)
        at AVLNode.insert(AVLNode.java:37)
         at AVLTest.main(AVLTest.java:22)

This is the test case that I am using: 60,10,61,9,8. It is when I'm adding 8 into the tree where I run into the error. I believe the error lies in the method itself but i'm not entirely sure on what's causing the problem. Any help would be greatly appreciated.

I was able to figure out the problem, the method will go into one of the double rotation methods and try to rotate the sub tree twice when it doesn't have to. Which explains the null pointer exception, the solution is to add a balance check for the tree in both of the double rotation methods.

 private AVLNode doubleRotateLeftRight(AVLNode rt) {
    if (getBalance(rt.left) < 0) {
        rt.left= rotateLeft(rt.left);
        return rotateRight(rt);
    } else {
        return rotateRight(rt);
    }
}

private AVLNode doubleRotateRightLeft(AVLNode rt) {
   if (getBalance(rt.right) > 0) {
        rt.right = rotateRight(rt.right);
        return rotateLeft(rt);
    } else {
        return rotateLeft(rt);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM