简体   繁体   English

AVL树左旋转

[英]AVL Tree Left Rotation

I'm righting an AVL Tree class and I'm having trouble with my "rotateLeft" method. 我正在修改一个AVL Tree类,我的“rotateLeft”方法遇到了问题。 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. 这是我正在使用的测试用例:60,10,61,9,8。 It is when I'm adding 8 into the tree where I run into the error. 当我在树中添加8时,我遇到了错误。 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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