AVL实现平衡二叉树

前提:默认树中不会有相同的值出现
实现了平衡二叉树基本的插入、删除、修改。考虑的情况可能不那么完整,欢迎给予建议~

整体代码如下:

import java.util.LinkedList;



class TreeNode{
     int value;
    TreeNode(int value){
         this.value=value;
    }
    TreeNode left;
    TreeNode right;
    int height;
}

public class AVLTree {
     //获得高度
     public int getHeight(TreeNode t){
          if(t==null) return 0;
          return Math.max(getHeight(t.left), getHeight(t.right))+1;
     }
     //插入节点
     public TreeNode insertNode(TreeNode root,int item){
          System.out.println("Insert "+item+" now:");
          //假设item是不和树中所有节点重复的值
          if(root==null){
               //树为空的时候
               root=new TreeNode(item);
               root.height=0;
          }
          else if(item<root.value){
               //树不空,要插入的item小于root,递归插入左子树。
               root.left=insertNode(root.left, item);
               if((getHeight(root.left)-getHeight(root.right))>1){
                    if(item<root.left.value){
                         //插在了root的左儿子的左结点,root失去平衡
                         root=singlewithLeft(root);
                    }else{
                         //插在了root的左儿子的右节点,root失去平衡
                         root=doublewithLeft(root);
                    }
               }

          }else{
               root.right=insertNode(root.right, item);
               if((getHeight(root.right)-getHeight(root.left))>1){
                    if(item>root.right.value){
                         //插在了root右儿子的右节点,root失去平衡
                         root=singlewithRight(root);
                    }else {
                         //插在了root的右儿子的左结点,root失去平衡
                         root=doublewithRight(root);
                    }
               }

          }
          return root;
     }
    //查询
     public boolean queryNode(TreeNode root,int item){
          //查询树中是否有节点的值是item,有返回true,否则返回False
          if(item==root.value){
               return true;
          }else if(root.left!=null && item<root.value){
               return queryNode(root.left, item);
          }else if (root.right!=null && item>root.value) {
               return queryNode(root.right, item);
          }
          return false;
     }
    //删除
     public TreeNode deleteNode(TreeNode root,int item){
          //删除值为item的节点
          if(item==root.value){
               if(root.left==null || root.right==null){
                    if(root.left!=null) root=root.left;
                    else if(root.right!=null) root=root.right;
                    else root=null;
               }else{
                    TreeNode tr=root.right;
                    if(tr.left!=null){
                         while(tr.left!=null) tr=tr.left;
                         root.value=tr.value;
                         tr=null;
                    }else{
                         root.value=tr.value;
                         root.right=tr.right;
                         tr=null;
                    }
                    //调整本层的root
                    root=fixBalance(root);
               }    
          }else  if(item<root.value){
               root.left=deleteNode(root.left, item);
               //回溯的过程中调整上一层的root
               root=fixBalance(root);
          }else{
               root.right=deleteNode(root.right, item);
               //回溯的过程中调整上一层的root
               root=fixBalance(root);
          }

          return root;
     }
     //修改
     public TreeNode updateNode(TreeNode root,int olditem,int newitem){
          //将值为olditem的节点的值更新为newitem,然后重新平衡
          //采取的方法是删除值为olditem的节点,插入值为newitem的节点
          root=deleteNode(root, olditem);
          return insertNode(root, newitem);
     }
    //平衡,用于删除节点的时候
     public TreeNode fixBalance(TreeNode t){
          System.out.println("fixBalance :"+ t.value);
          if((getHeight(t.left)-getHeight(t.right))>1){
               //左子树比右子树高
               TreeNode tl=t.left;
               if(tl.left!=null && (tl.left.left!=null || tl.left.right!=null)){
                    //左儿子的左子树加了节点
                    System.out.println("fix by singlewithleft");
                    return singlewithLeft(t);
               }
               if(tl.right!=null && (tl.right.left!=null || tl.right.right!=null)){
                    //左儿子的右子树加了节点
                    System.out.println("fix by doublewithleft");
                    return doublewithLeft(t);
               }
          }
          if((getHeight(t.right)-getHeight(t.left))>1){
               //右子树比左子树高
               TreeNode tr=t.right;
               if(tr.left!=null && (tr.left.left!=null|| tr.left.right!=null)){
                    //右儿子的左子树加了节点
                    System.out.println("fix by doublewithright");
                    return doublewithRight(t);
               }
               if(tr.right!=null && (tr.right.left!=null || tr.right.right!=null)){
                    System.out.println("fix by singlewithright");
                    return singlewithRight(t);
               }
          }
          return t;
     }
     //判断一棵树是不是平衡树
     public boolean isAVL(TreeNode root){
          if(root==null) return true;
          if(root.left==null && root.right==null){
               if(Math.abs(getHeight(root.left)-getHeight(root.right))>1){
                    return false;
               }
          }
          return isAVL(root.left)&&isAVL(root.right);
     }
    //向右转
     public TreeNode singlewithLeft(TreeNode t){
          //左儿子的左结点插入了新的节点
          System.out.println("A");
          TreeNode tl=t.left;
          TreeNode tlr=tl.right;
          tl.right=t;
          t.left=tlr;
          t.height=getHeight(t);
          tl.height=getHeight(tl);
          return tl;
     }
     //向左转
     public TreeNode singlewithRight(TreeNode t){
          System.out.println("B");
          //右儿子的右节点插入了新的节点
          TreeNode tr=t.right;
          TreeNode trl=tr.left;
          t.right=trl;
          tr.left=t;
          t.height=getHeight(t);
          tr.height=getHeight(tr);
          return tr;
     }
     //先向左转,再右转
     public TreeNode doublewithLeft(TreeNode t){
          System.out.println("C");
          //左儿子的右子树插入了新的节点
          TreeNode tleft=t.left;
          t.left=singlewithRight(tleft);
          return singlewithLeft(t);
     }
     //先向右转,再左转
     public TreeNode doublewithRight(TreeNode t){
          System.out.println("D");
          //右儿子的左子树插入了新的节点
          t.right=singlewithLeft(t.right);
          return singlewithRight(t);
     }
     //层次遍历
     public void printByCeng(TreeNode root){
          //层次遍历 空的地方填充-1
          if(root==null) {
               return;
          }
          LinkedList<TreeNode> q=new LinkedList<TreeNode>();
          q.add(root);
          while(q.size()!=0){
               TreeNode pNode=q.poll();
               if(pNode.value==-1){
                    System.out.println(pNode.value);
               }else{
                    System.out.println(pNode.value);
                if(pNode.left!=null){
                         q.add(pNode.left);
                    }else if(pNode.right!=null){
                         q.add(new TreeNode(-1));
                    }
                    if(pNode.right!=null){
                         q.add(pNode.right);
                    }else if(pNode.left!=null){
                         q.add(new TreeNode(-1));
                    }
               }
          }
     }
     public static void main(String args[]){
          AVLTree test=new AVLTree();
          int[] nums={2,9,7,11,5,23,48,34};
          int i=0;
          TreeNode root = null;
          while(i<nums.length){
               int item=nums[i++];
               root=test.insertNode(root, item);
               test.printByCeng(root);              
          }
          System.out.println("----------------------");
          test.printByCeng(root);
          System.out.println("----------------------");
          System.out.println("delete 5:");
          root=test.deleteNode(root, 5);
          test.printByCeng(root);
          System.out.println("----------------------");
          System.out.println("delete 23");
          root=test.deleteNode(root, 23);
          test.printByCeng(root);
          System.out.println("----------------------");
          System.out.println("update 34 to 1");
          root=test.updateNode(root, 34, 1);
          test.printByCeng(root);
          System.out.println("----------------------");
          System.out.println("query 7");
          System.out.println(test.queryNode(root, 7));
         System.out.println("query 66");
          System.out.println(test.queryNode(root, 66));


     }
}

/*
Output:
Insert 2 now:
2
Insert 9 now:
Insert 9 now:
2
-1
9
Insert 7 now:
Insert 7 now:
Insert 7 now:
D
A
B
7
2
9
Insert 11 now:
Insert 11 now:
Insert 11 now:
7
2
9
-1
11
Insert 5 now:
Insert 5 now:
Insert 5 now:
7
2
9
-1
5
-1
11
Insert 23 now:
Insert 23 now:
Insert 23 now:
Insert 23 now:
B
7
2
11
-1
5
9
23
Insert 48 now:
Insert 48 now:
Insert 48 now:
Insert 48 now:
7
2
11
-1
5
9
23
-1
48
Insert 34 now:
Insert 34 now:
Insert 34 now:
Insert 34 now:
Insert 34 now:
D
A
B
7
2
11
-1
5
9
34
23
48
----------------------
7
2
11
-1
5
9
34
23
48
----------------------
delete 5:
fixBalance :2
fixBalance :7
fix by singlewithright
B
11
7
34
2
9
23
48
----------------------
delete 23
fixBalance :34
fixBalance :11
11
7
34
2
9
-1
48
----------------------
update 34 to 1
fixBalance :11
Insert 1 now:
Insert 1 now:
Insert 1 now:
Insert 1 now:
A
7
2
11
1
-1
9
48
----------------------
query 7
true
query 66
false

*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值