无法在java

时间:2015-06-10 03:17:08

标签: java binary-search-tree avl-tree

大家好我一直在尝试实现AVL树但没有成功。我正在练习获得这个概念。到目前为止,我已成功插入树,获取树的高度,检查它是否平衡,树中的节点数,查找三个中的最小值和最大值,并检查值是否在树中。现在,我正在尝试在树中插入新节点时平衡树,但没有成功。请问你能指导我做错了什么。以下是我的结果的代码。请耐心等待。 下面是我的节点类: BinaryNode.java

public class BinaryNode<T> {

private T data;
private BinaryNode<T> rightChild;
private BinaryNode<T> leftChild;

public BinaryNode(){}

public BinaryNode(T data){
    this(data, null, null);
}
public BinaryNode(T data, BinaryNode<T> leftChild, BinaryNode<T> rightChild){
    this.data = data;
    this.leftChild = leftChild;
    this.rightChild = rightChild;
}

public void setLeftChild(BinaryNode<T> leftChild){
    this.leftChild = leftChild;
}

public void setRightChild(BinaryNode<T> rightChild){
    this.rightChild = rightChild;
}
public BinaryNode<T> getRightChild() {
    return rightChild;
}
public BinaryNode<T> getLeftChild() {
    return leftChild;
}

public T getData(){
    return data;
}
public int Height(){
    return getHeight(this);
}
//returns the height of the tree
private int getHeight(BinaryNode<T> root){
    if(root == null){
        return -1;
    }
    else
        return 1+Math.max(getHeight(root.getLeftChild()), getHeight(root.getRightChild()));
}

//functions get the number of nodes availabe in the tree
protected int getNumberOfNodes(){
   int a=0,b=0;
   if(leftChild!=null){
       a = leftChild.getNumberOfNodes();
           }

       if(rightChild!=null){
       b = rightChild.getNumberOfNodes();
       }
   return a+b+1;
}

 public void balance(){
   balance(this);
 }
private void balance(BinaryNode<T> root){
   int balance = getHeight(root.getLeftChild())-getHeight(root.getRightChild());
   if(balance>2){
       if(getHeight(root.getLeftChild())>=getHeight(root.getRightChild())){
           rotateRight(root);
       }
       else{
           doubleRotateRight(root);
       }
   }
   else if(balance<-2){
       if(getHeight(root.getRightChild())>=getHeight(root.getLeftChild())){
           rotateLeft(root);
       }
       else{
           doubleRotateLeft(root);
       }
   }
   else{
       getHeight(root);
   }
 }
//right right rotation
private BinaryNode<T> rotateRight(BinaryNode<T> root){
    BinaryNode<T> nodeA = root.getLeftChild();
    root.setLeftChild(nodeA.getRightChild());
    nodeA.setRightChild(root);
    return nodeA;
}

//left left rotation
private BinaryNode<T> rotateLeft(BinaryNode<T> root){
    BinaryNode<T> nodeA = root.getRightChild();
    root.setRightChild(nodeA.getLeftChild());
    nodeA.setLeftChild(root);
    return nodeA;
}

//right left rotation
private BinaryNode<T> doubleRotateLeft(BinaryNode<T> root){
    BinaryNode<T> nodeA = root.getLeftChild();
    root.setRightChild(rotateRight(nodeA));
    return rotateLeft(root);
}
//left right rotation
private BinaryNode<T> doubleRotateRight(BinaryNode<T> root){
    BinaryNode<T> nodeA = root.getRightChild();
    root.setLeftChild(rotateLeft(nodeA));
    return rotateRight(root);
}


}

BinarySearchTree:

public class BinarySearchTree<T extends Comparable<? super T>> {

private BinaryNode<T> root;

public BinarySearchTree() {}

public BinarySearchTree(T data){
    root = new BinaryNode<T>(data);
}

public void insert(T data){

    BinaryNode<T> newNode = new BinaryNode<T>(data);
    if(isEmpty()){
        root = newNode;
    }
    else
        insertElements(root, newNode);
}
private void insertElements(BinaryNode<T> root, BinaryNode<T> newNode){
    if(newNode.getData().compareTo(root.getData())<0){
        if(root.getLeftChild()==null){
            root.setLeftChild(newNode);
        }
        else
            insertElements(root.getLeftChild(), newNode);
            //balance(root.getLeftChild());
    }
    else{
        if(root.getRightChild()==null){
            root.setRightChild(newNode);
        }
        else{
            insertElements(root.getRightChild(), newNode);
            //balance(root.getRightChild()); 
        }
    }
    balance(root);
}
public void balance(BinaryNode<T> root){
    root.balance();
}
public boolean isEmpty(){
    return (root==null);
}

public void preOrder(){
    preOrder(root);
}

private void preOrder(BinaryNode<T> root){
    if(root == null){
        return;
    }
    else{
        System.out.println(root.getData());
        preOrder(root.getLeftChild());
        preOrder(root.getRightChild());
    }
}
public int getHeight(){
    return root.Height();
}
//gets the number of nodes in the tree
public int getNumberOfNodes(){
    return root.getNumberOfNodes();
}
//returns true or false if tree is balanced
 public boolean isBalanced(){
       if(root==null){
           return true;
       }
           if(checkHeight(root)==-1){
               return false;
           }
           else{
               return true;
       }
   }

 //checks to see if the tree is balanced. 
 private int checkHeight(BinaryNode<T> root){
     if(root==null){
         return 0;
     }
     int left = checkHeight(root.getLeftChild());
     int right = checkHeight(root.getRightChild());
     if(left==-1||right==-1){
         return -1;
     }
     if(Math.abs(left-right)>1){
         return -1;
     }
     else
         return Math.max(left, right)+1;
 }
 public T findMin(){
     return findMin(root);
 }

 private T findMin(BinaryNode<T> root){
     if(root==null){
         return null;
     }
     else if(root.getLeftChild()==null){
         return root.getData();
     }
     else
         return findMin(root.getLeftChild());

 }
 public T findMax(){
     return findMax(root);
 }
 private T findMax(BinaryNode<T> root){
     if(root==null){
         return null;
     }
     else if(root.getRightChild()==null){
         return root.getData();
     }
     else return findMax(root.getRightChild());
 }

 public boolean contains(T entry){
     return contains(root, entry);
 }
 private boolean contains(BinaryNode<T> root, T entry){
    if(root == null){
        return false;
    }
    else if(entry.compareTo(root.getData())<0){
        return contains(root.getLeftChild(), entry);
    }
    else if(entry.compareTo(root.getData())>0){
        return contains(root.getRightChild(), entry);
    }
    else{
        if(entry.compareTo(root.getData())==0){
        return true;
        }
        else
            return false;
    }

 }
 public void makeEmpty(){
     this.root = null;
  }
}

测试类:

public class Test {

public static void main(String[] args) {
    // TODO Auto-generated method stub
        BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>();
        tree.insert(5);
        tree.insert(10);
        tree.insert(20);

        tree.preOrder(); //prints out the tree in a pre-order list

        System.out.println("Height of tree: " +tree.getHeight());
        System.out.println("Number of Nodes: "+tree.getNumberOfNodes());
        System.out.println("Balanced: "+tree.isBalanced());
        System.out.println("Find max:  "+ tree.findMax());
        System.out.println("Find min: "+tree.findMin());
        System.out.println("Contains: "+tree.contains(1));
 }
}

以下是结果。但我错了,因为树不平衡。似乎有些不对劲。每当我插入一个新节点时,我也会平衡尝试平衡树。请有人帮帮我,发现我做错了什么。如果代码冗长,我会道歉。 结果:

5
10
20
Height of tree: 2
Number of Nodes: 3
Balanced: false
Find max:  20
Find min: 5
Contains: false

1 个答案:

答案 0 :(得分:0)

如果左右子树的高度相差多于一个,则您的方法BinarySearchTree#checkHeight(BinaryNode<T> root)会报告树不平衡。但是,当您插入节点时,它最终会调用方法BinaryNode#balance(BinaryNode<T> root),除非子树高度相差超过2,否则不会旋转节点。当高度相差更多时,您需要修改后一种方法来旋转节点而且,在该方法的getHeight(root)情况下对else的调用似乎毫无用处。

可能还有其他问题,但这是我见过的唯一问题。