数据结构-树-平衡二叉搜索树

平衡二叉搜索树的定义

前言

Java实现平衡二叉搜索树的定义,代码是参考(copy)文章的代码定义,在原来的基础上添加了树的层次遍历,并且层次遍历可以打印出层序,增加了更多的测试用例,期待后面可以增加结点的删除功能。

代码

2.1节点的定义

/**
 * 平衡二叉搜索树节点定义
 */
public class AVLNode {
    /** 数据 **/
    public int data;
    /** 相对高度 **/
    public int height;
    /** 父节点 **/
    public AVLNode parent;
    /** 左子树 **/
    public AVLNode left;
    /** 右子树 **/
    public AVLNode right;
    public AVLNode(int data) {
        this.data = data;
        this.height = 1;
    }
}

2.2 平衡二叉树的定义

/**
 * 模仿AVLTree写出二叉树的平衡
 *
 * @author Caolele
 * @since 12-19-2022 周一
 */

public class AVLTreeImitation {

    AVLNode root;


    public void insert(int data){

        if(root == null){
            root = new AVLNode(data);
        }else {
            root = insert(root, data);
        }
    }


    AVLNode insert(AVLNode root,int data){
        if(data <root.data){
            if(root.left == null){
                root.left = new AVLNode(data);
                root.left.parent = root.left;
            }else {
                root.left = insert(root.left, data);
            }
        }else {

            if(root.right == null)
            {
                root.right = new AVLNode(data);
                root.right.parent = root.right;
            }else {
                root.right = insert(root.right, data);
            }
        }

        //走到这一步一定是新插入了节点,所以需要当前节点的高度
        root.height = calcHeight(root);

        //开始进行旋转使之满足平衡搜索二叉树的定义

        if(calcBF(root) == 2){ //若是LL型仅需右旋
            if( -1 == calcBF(root.left)){  //判断是否需要左旋
                root.left = leftRotate(root.left);
            }
            root = rightRotate(root);
        }

        if(calcBF(root) == -2){ //若是LL型仅需右旋
            if( 1 == calcBF(root.right)){  //判断是否需要左旋
                root.right = rightRotate(root.right);
            }
            root = leftRotate(root);
        }

        return root;
    }

    public AVLNode leftRotate(AVLNode root) {
        AVLNode parent = root.parent;
        AVLNode newNode = root.right;
        AVLNode oldNode = root;

        if (parent != null) {
            if (parent.data > newNode.data) {
                parent.left = newNode;

            } else {
                parent.right = newNode;
            }
            newNode.parent = parent;
        }

        AVLNode left = newNode.left;

        newNode.left = oldNode.right;
        oldNode.parent = newNode;

        if (left != null) {
            left.parent = oldNode;
        }
        oldNode.right = left; //当left为null时,让oldNode.right 赋值为null

        //这里要先计算旧节点的高度才能在此基础上计算新节点的高度
        oldNode.height = calcHeight(oldNode);
        newNode.height = calcHeight(newNode);
        return newNode;
    }


    /**
     * 右旋
     * @param root
     * @return
     */

    AVLNode rightRotate(  AVLNode root) {
        AVLNode parent = root.parent;
        AVLNode newNode = root.left;
        AVLNode oldNode = root;

        if(parent!=null){
            if(parent.data>newNode.data){
                parent.left = newNode;
            }else {
                parent.right  = newNode;
            }

            newNode.parent = parent;
        }
        AVLNode right = newNode.right;
        newNode.right  = oldNode;
        oldNode.parent  = newNode;

        if(right != null){
            right.parent = oldNode;
        }
        oldNode.left = right;//当right为null时,让oldNode.left 赋值为null


        oldNode.height = calcHeight(oldNode);
        newNode.height = calcHeight(newNode);

        return newNode;

    }

    /**
     * 计算结点的平衡因子
     *
     * @param root
     * @return
     */
    int calcBF(AVLNode root) {

        if (root == null) {
            return 0;
        } else if (root.left == null) {
            return -root.right.height;
        } else if (root.right == null) {
            return root.left.height;
        } else if (root.left == null && root.right == null) {
            return 0;
        } else {
            return root.left.height - root.right.height;
        }
    }

    /**
     * 计算Node的高度
     *
     * @param root
     * @return
     */
    int calcHeight(AVLNode root) {
        if (root.left == null && root.right == null) {
            return 1;
        } else if (root.left == null) {
            return root.right.height + 1;
        } else if (root.right == null) {
            return root.left.height + 1;
        } else {
            if (root.left.height >= root.right.height) {
                return root.left.height + 1;
            } else {
                return root.right.height + 1;
            }
        }
    }

    public static void main(String[] args) {
        AVLTree tree = new AVLTree();

        //test1
//        tree.insert(1);
//        tree.insert(2);
//        tree.insert(3);

        //test2
//        tree.insert(3);
//        tree.insert(2);
//        tree.insert(1);

        //test3
//        tree.insert(1);
//        tree.insert(3);
//        tree.insert(2);

        //test4
//        tree.insert(3);
//        tree.insert(1);
//        tree.insert(2);

        //test5
        tree.insert(10);
        tree.insert(4);
        tree.insert(14);
        tree.insert(3);
        tree.insert(6);
        tree.insert(5);
        levelTraverse(tree.root);
    }

    //层序遍历
    private static void levelTraverse(AVLNode root) {

        if (root == null) {
            return;
        }

        List<AVLNode> list = new LinkedList<>();
        list.add(root);


        AVLNode nLast = root;


        while (!list.isEmpty()) {
            AVLNode pop = list.remove(0);

            System.out.print(pop.data+"\t");
            if (pop.left != null) {
                list.add(pop.left);
            }
            if (pop.right != null) {
                list.add(pop.right);
            }

            //此时第上层遍历完毕,并且下一层也完全装入到了队列
            if(pop == nLast  && !list.isEmpty()){
                System.out.println();
                nLast = list.get(list.size()-1);
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值