算法与数据结构系列之[平衡二叉树-AVL树-下]

上篇介绍了AVL树的概述,这篇把AVL树的java代码实现贴出来

public class AVLTree<K extends Comparable<K>, V> {

   private class Node{
       public K key;
       public V value;
       public Node left, right;
       public int height; //树的高度

       public Node(K key, V value){
           this.key = key;
           this.value = value;
           left = null;
           right = null;
           height = 1;
       }
   }

   private Node root;  //根节点
   private int size;  //元素个数

   public AVLTree(){
       root = null;
       size = 0;
   }
   
    //获取元素个数
   public int getSize(){
       return size;
   }
   
       //判断AVL树是否为空
   public boolean isEmpty(){
       return size == 0;
   }

   //获取节点的高度
   private int getHeight(Node node){
       if(node == null)
           return 0;
       return node.height;
   }

   //获得节点的平衡因子
   private int getBalanceFactor(Node node){
       if(node == null)
           return 0;
       return getHeight(node.left) - getHeight(node.right);
   }

   //判断是否是二分搜索树
   private boolean isBST(){
       ArrayList<K> keys = new ArrayList<>();
       inOrder(root,keys);
       for (int i = 1; i < keys.size(); i++) {
           if(keys.get(i-1).compareTo(keys.get(i)) > 0)
               return false;
       }
       return true;
   }
   
    //中序遍历
   public void inOrder(Node node, ArrayList<K> keys){
       if(node == null)
           return;
       inOrder(node.left,keys);
       keys.add(node.key);
       inOrder(node.right,keys);
   }

   //判断二叉树是否是一棵平衡二叉树
   public boolean isBalanced(){
       return isBalanced(root);
   }

   private boolean isBalanced(Node node){
       if(node == null)
           return true;
       int balanceFactor = getBalanceFactor(node);
       if(Math.abs(balanceFactor) >1)
           return false;
       return isBalanced(node.left)&&isBalanced(node.right);
   }

   //右旋转
   private Node rightRotate(Node y){
       Node x = y.left;
       Node T3 = x.right;
       //向右旋转
       x.right = y;
       y.left = T3;
       //更新height值,旋转后只有x和y的高度值发生变化
       y.height = Math.max(getHeight(y.left),getHeight(y.right)) + 1;
       x.height = Math.max(getHeight(x.left),getHeight(x.right)) + 1;
       return x;
   }

   //左旋转
   private Node leftRotate(Node y){
       Node x = y.right;
       Node T3 = x.left;
       //向左旋转
       x.left = y;
       y.right = T3;
       //更新height值,旋转后只有x和y的高度值发生变化
       y.height = Math.max(getHeight(y.left),getHeight(y.right)) + 1;
       x.height = Math.max(getHeight(x.left),getHeight(x.right)) + 1;
       return x;
   }

   // 向AVL树添加新的元素(key, value)
   public void add(K key, V value){
       root = add(root, key, value);
   }

   // 向以node为根的AVL树中插入元素(key, value),递归算法
   // 返回插入新节点后AVL树的根
   private Node add(Node node, K key, V value){

       if(node == null){
           size ++;
           return new Node(key, value);
       }

       if(key.compareTo(node.key) < 0)
           node.left = add(node.left, key, value);
       else if(key.compareTo(node.key) > 0)
           node.right = add(node.right, key, value);
       else // key.compareTo(node.key) == 0
           node.value = value;
       //更新height
       node.height = 1 + Math.max(getHeight(node.left),getHeight(node.right));
       //计算平衡因子
       int balanceFactor = getBalanceFactor(node);
       //平衡维护
       //LL
       if(balanceFactor > 1 && getBalanceFactor(node.left) >= 0)
           rightRotate(node);
       //RR
       if(balanceFactor < -1 && getBalanceFactor(node.right) <= 0)
           return leftRotate(node);
       //LR
       if(balanceFactor > 1 && getBalanceFactor(node.left) < 0){
           node.left = leftRotate(node.left);
           return rightRotate(node);
       }
       //RL
       if(balanceFactor < -1 && getBalanceFactor(node.right) > 0){
           node.right = rightRotate(node.right);
           return leftRotate(node);
       }
       return node;
   }

   // 返回以node为根节点的AVL树中,key所在的节点
   private Node getNode(Node node, K key){

       if(node == null)
           return null;

       if(key.equals(node.key))
           return node;
       else if(key.compareTo(node.key) < 0)
           return getNode(node.left, key);
       else // if(key.compareTo(node.key) > 0)
           return getNode(node.right, key);
   }
   
    //判断AVL树中是否包含key
   public boolean contains(K key){
       return getNode(root, key) != null;
   }
   
    //获取AVL树中键为key的value值
   public V get(K key){

       Node node = getNode(root, key);
       return node == null ? null : node.value;
   }
   
       //将AVL树中键为key的value值设置成新的newValue值
   public void set(K key, V newValue){
       Node node = getNode(root, key);
       if(node == null)
           throw new IllegalArgumentException(key + " doesn't exist!");

       node.value = newValue;
   }

   // 返回以node为根的AVL树的最小值所在的节点
   private Node minimum(Node node){
       if(node.left == null)
           return node;
       return minimum(node.left);
   }

   // 从AVL树中删除键为key的节点

   public V remove(K key){

       Node node = getNode(root, key);
       if(node != null){
           root = remove(root, key);
           return node.value;
       }
       return null;
   }

   private Node remove(Node node, K key){

       if( node == null )
           return null;
       Node retNode; //要返回的node节点,
       if( key.compareTo(node.key) < 0 ){
           node.left = remove(node.left , key);
           retNode = node;
       }
       else if(key.compareTo(node.key) > 0 ){
           node.right = remove(node.right, key);
           retNode = node;
       }
       else{   // key.compareTo(node.key) == 0

           // 待删除节点左子树为空的情况
           if(node.left == null){
               Node rightNode = node.right;
               node.right = null;
               size --;
               retNode = node;
           }

           // 待删除节点右子树为空的情况
           else if(node.right == null){
               Node leftNode = node.left;
               node.left = null;
               size --;
               retNode = node;
           }
           // 待删除节点左右子树均不为空的情况
           // 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
           // 用这个节点顶替待删除节点的位置
           else {
               Node successor = minimum(node.right);
               successor.right = remove(node.right, successor.key);
               successor.left = node.left;

               node.left = node.right = null;

               retNode = node;
           }
       }
       if(retNode == null)
           return null;
       //更新height
       retNode.height = 1 + Math.max(getHeight(retNode.left),getHeight(retNode.right));
       //计算平衡因子
       int balanceFactor = getBalanceFactor(retNode);
       //平衡维护
       //LL
       if(balanceFactor > 1 && getBalanceFactor(retNode.left) >= 0)
           rightRotate(retNode);
       //RR
       if(balanceFactor < -1 && getBalanceFactor(retNode.right) <= 0)
           return leftRotate(retNode);
       //LR
       if(balanceFactor > 1 && getBalanceFactor(retNode.left) < 0){
           retNode.left = leftRotate(retNode.left);
           return rightRotate(retNode);
       }
       //RL
       if(balanceFactor < -1 && getBalanceFactor(retNode.right) > 0){
           retNode.right = rightRotate(retNode.right);
           return leftRotate(retNode);
       }
       return retNode;
   }

   public static void main(String[] args) {
       int[] arr = {12,8,18,5,11,17,4};
       AVLTree avlTree = new AVLTree();
       for (int i = 0; i < arr.length; i++) {
           avlTree.add(arr[i],arr[i]);
       }
       System.out.println("AVLTree is balanced: " + avlTree.isBalanced());

       avlTree.add(2,2);
       avlTree.add(7,7);
       System.out.println("AVLTree is balanced: " + avlTree.isBalanced());

       avlTree.remove(18);
       System.out.println("AVLTree is balanced: " + avlTree.isBalanced());
   }
}
上一篇:算法与数据结构系列之[平衡二叉树-AVL树-上]


下一篇:1123 Is It a Complete AVL Tree