繁体   English   中英

无法在Java中实现AVL树

[英]Trouble implementing avl tree in java

大家好,我一直在尝试实现AVL树,但没有成功。 我正在练习以获取概念。 到目前为止,我已经成功地插入到树中,获取了树的高度,检查树是否平衡,树中的节点数,找到三个中的min和Max值,并检查树中是否有值。 现在,我试图在树中插入新节点但没有成功的同时平衡树。 请您指导我做错了什么。 下面是我的代码和结果。 请忍受和感谢。 下面是我的节点类: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

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

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

暂无
暂无

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

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