• JAVA实现二叉平衡树


    JAVA代码实现

    package main.com.Tree;
    
    class AvlNode{
        //每个节点中储存的数据
        int data;
        //左孩子节点
        AvlNode lNode;
        //右节点
        AvlNode rNode;
        //树的高度,用于判断树是否平衡
        int height;
        public AvlNode(int data){
            this.data=data;
            //初始高度是1,即只有一个根节点
            this.height=1;
        }
    }
    public class AvlTree {
    
        //获取一棵树的高度
        public static int height(AvlNode node){
            //如果树是空,那么高度也就是0
            return node==null ? 0 : node.height;
        }
    
    
        //判断当前树是否平衡,用来判断树是否需要旋转
        public static boolean isBalanced(AvlNode node){
            //如果高度小于等于1,那么就是一个只有根节点,是平衡树。
            if(height(node)<=1){return true;}
            //计算左右分支的高度差,小于等于1的就是平衡树
    
            return Math.abs(height(node.lNode)-height(node.rNode))<=1;
        }
    
        //右旋
        /*
                     ----->
               3                2
              /                / 
            2                 1   3
           /
          1
        */
        public static AvlNode Right_Rotate(AvlNode node){
            //用来存放根节点
            AvlNode root;
            //左旋操作
            root=node.lNode;
            node.lNode=root.rNode;
            root.rNode=node;
            //重新计算计算节点高度
            node.height=Math.max(height(node.lNode),height(node.rNode))+1;
            root.height=Math.max(height(root.lNode),height(root.rNode))+1;
            //返回旋转之后的树
            return root;
        }
    
    
        /*左旋
                ----->
         1                 2
                         /  
           2             1    3
            
             3
         */
        public static AvlNode Left_Rotate(AvlNode node){
            AvlNode root;
            root=node.rNode;
            node.rNode=root.lNode;
            root.lNode=node;
            //上面只对node节点(也就是图中的1节点)root节点(也就是2节点)进行了操作,所以下面对其进行高度的重新计算
            node.height=Math.max(height(node.lNode),height(node.rNode))+1;
            root.height= Math.max(height(root.lNode),height(root.rNode))+1;
            return root;
        }
    
        /*左右,先左旋,再右旋
                ------>       ------->
          3              3                2
         /              /                / 
        1              2                1   3
                     /
          2          1
         */
        public static AvlNode Left_Right_Rotate(AvlNode node){
            AvlNode root;
            //先将node的左子树左旋
            node.lNode=Left_Rotate(node.lNode);
            //然后将node右旋
            root=Right_Rotate(node);
            return root;
        }
    
        /*先右旋,再左旋。
              --------->           ---------->
          3               3                      4
                                              / 
            5               4                  3   5
           /                 
          4                   5
    
         */
        public static AvlNode Right_Left_Rotate(AvlNode node){
            AvlNode root;
            //将右子树右旋
            node=Right_Rotate(node.rNode);
            //再将node树左旋
            root=Left_Rotate(node);
            return root;
        }
    
        //node:是目标树。
        //data:要插入到目标树的数据
        public static AvlNode insert(AvlNode node,int data){
            AvlNode insertNode=new AvlNode(data);
            //首先判断node是不是空
            if(node==null) {
                //如果是空那么新插入的节点就是跟节点
                return insertNode;
            }
            if(data>node.data){
                //插入数据大于当前节点,遍历右节点
                node.rNode=insert(node.rNode,data);
                //插入完成后计算节点的高度
                node.height=Math.max(height(node.lNode),height(node.rNode))+1;
                //进行平衡操作
                if(!isBalanced(node)){
                    //如果树不平衡,则进行平衡操作。
                    //因为是插入的右节点。所以只可能是:右-右型和左右型
                    if(data<node.rNode.data){
                        //如果插入的数据小于node的右节点就是:右左型
                        node=Right_Left_Rotate(node);
                    }else{
                        //否则就是:右右型
                        node=Left_Rotate(node);
                    }
                }
            }else{
                //小于等于都往左边插入
                node.lNode=insert(node.lNode,data);
                //插入完成后计算节点的高度
                node.height=Math.max(height(node.lNode),height(node.rNode))+1;
                //处理平衡
                if(!isBalanced(node)){
                    if(data>node.lNode.data){
                        //左右型
                        node=Left_Right_Rotate(node);
                    }else{
                        //左左型
                        node=Right_Rotate(node);
                    }
                }
            }
    
    
            return node;
        }
    }
    
    

    测试代码

    public class TreeTest {
    
        public static void main(String[] args) {
            AvlNode tree=AvlTree.insert(null,1);
            tree=AvlTree.insert(tree,2);
            tree=AvlTree.insert(tree,3);
            tree=AvlTree.insert(tree,4);
            tree=AvlTree.insert(tree,5);
            tree=AvlTree.insert(tree,6);
            tree=AvlTree.insert(tree,7);
            tree=AvlTree.insert(tree,8);
    
        }
    }
    

    可以使用IDEA的debug查看树的结构

    作者:BobC

    文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。
  • 相关阅读:
    谈To B产品路径逻辑:To B产品的核心本质到底是什么?
    做产品应该遵循哪些宏观产品原则?
    做产品应该遵循哪些微观产品原则?
    B端产品的第一性原理思考
    美团点评王慧文:互联网有AB面,最惨烈战争发生在B2
    《罗振宇 知识就是力量》
    生活是一只龙虾
    CAD-美的热水器F50-32DQ
    CAD-椭圆和圆弧命令
    CAD-圆命令
  • 原文地址:https://www.cnblogs.com/Eastry/p/12738672.html
Copyright © 2020-2023  润新知