数据结构之平衡二叉树(AVL)

一、基础知识
在这里插入图片描述
二、AVL树高度求解

package com.ws.数据结构..平衡二叉树AVL.创建与高度;

public class AVLTree {
    public static void main(String[] args) {
        int[] arr={4,3,6,5,7,8};
        //创建平衡二叉树对象
        AVL avl=new AVL();
        //添加节点
        for (int i=0;i<arr.length;i++){
            avl.add(new Node(arr[i]));
        }
        //遍历平衡二叉树
        System.out.println("遍历平衡二叉树");
        avl.zhongprintf();

        System.out.println("没有旋转之前");
        System.out.println("树的高度="+avl.getRoot().height());
        System.out.println("左子树的高度="+avl.getRoot().zuoHeight());
        System.out.println("右子树的高度="+avl.getRoot().youHeight());

    }
}
//创建节点
class Node{
    int value;
    Node zuo;
    Node you;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    //添加节点
    //递归形式添加平衡二叉排序树
    public void add(Node node){
        if (node==null){
            return;
        }
        //判断传入节点值和子树的根节点的值的关系
        if (node.value<this.value){
            //小于  当前树左子节点为空,就直接挂上
            if (this.zuo==null){
                this.zuo=node;
            }else {
                //递归左子树添加
                this.zuo.add(node);
            }
        }else {
            //大于 当前右子节点为空,就直接挂上
            if (this.you==null){
                this.you=node;
            }else {
                //递归向右子树添加
                this.you.add(node);
            }
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (this.zuo!=null){
            this.zuo.zhongprintf();
        }
        System.out.println(this);
        if (this.you!=null){
            this.you.zhongprintf();
        }
    }

    //返回当前节点的高度 以该节点为根节点的树的高度
    public int height(){
        return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
    }

    //返回左子树的额高度
    public int zuoHeight(){
        if (zuo==null){
            return 0;
        }
        return zuo.height();
    }

    //返回右子树的高度
    public int youHeight(){
        if (you==null){
            return 0;
        }
        return you.height();
    }
}
//创建AVL树
class AVL{
    private Node root;

    public Node getRoot() {
        return root;
    }

    //添加节点方法
    public void add(Node node){
        //根节点是空,就直接添加
        if (root==null){
            root=node;
        }else {
            root.add(node);
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (root!=null){
            root.zhongprintf();
        }else {
            System.out.println("当前平衡二叉树为空,不能遍历");
        }
    }
}
遍历平衡二叉树
Node{value=3}
Node{value=4}
Node{value=5}
Node{value=6}
Node{value=7}
Node{value=8}
没有旋转之前
树的高度=4
左子树的高度=1
右子树的高度=3




三、AVL树左旋转
在这里插入图片描述

package com.ws.数据结构..平衡二叉树AVL.左旋转;

public class AVLTree {
    public static void main(String[] args) {
        int[] arr={4,3,6,5,7,8};
        //创建平衡二叉树对象
        AVL avl=new AVL();
        //添加节点
        for (int i=0;i<arr.length;i++){
            avl.add(new Node(arr[i]));
        }
        //遍历平衡二叉树
        System.out.println("遍历平衡二叉树");
        avl.zhongprintf();

        System.out.println("旋转之后");
        System.out.println("树的高度="+avl.getRoot().height());//4
        System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//1
        System.out.println("右子树的高度="+avl.getRoot().youHeight());//3


    }
}

//创建节点
class Node{
    int value;
    Node zuo;
    Node you;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    //添加节点
    //递归形式添加平衡二叉排序树
    public void add(Node node){
        if (node==null){
            return;
        }
        //判断传入节点值和子树的根节点的值的关系
        if (node.value<this.value){
            //小于  当前树左子节点为空,就直接挂上
            if (this.zuo==null){
                this.zuo=node;
            }else {
                //递归左子树添加
                this.zuo.add(node);
            }
        }else {
            //大于 当前右子节点为空,就直接挂上
            if (this.you==null){
                this.you=node;
            }else {
                //递归向右子树添加
                this.you.add(node);
            }
        }

        //当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
        if (youHeight()-zuoHeight()>1){
            zuoRotate();//左旋转
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (this.zuo!=null){
            this.zuo.zhongprintf();
        }
        System.out.println(this);
        if (this.you!=null){
            this.you.zhongprintf();
        }
    }

    //返回当前节点的高度 以该节点为根节点的树的高度
    public int height(){
        return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
    }

    //返回左子树的额高度
    public int zuoHeight(){
        if (zuo==null){
            return 0;
        }
        return zuo.height();
    }

    //返回右子树的高度
    public int youHeight(){
        if (you==null){
            return 0;
        }
        return you.height();
    }

    //左旋转
    private void zuoRotate(){
        //创建新的节点,值是当前节点
        Node newNode=new Node(value);
        //把新的节点的左子树设置成当前节点的左子树
        newNode.zuo=zuo;
        //把新节点的右子树设置成当前节点的右子树的左子树
        newNode.you=you.zuo;
        //把当前节点的值换成右子树的值
        value=you.value;
        //把当前节点的右子树设置成当前节点的右子树的右子树
        you=you.you;
        //把当前节点的左子节点设置成新的节点
        zuo=newNode;
    }
}

//创建AVL树
class AVL{
    private Node root;

    public Node getRoot() {
        return root;
    }

    //添加节点方法
    public void add(Node node){
        //根节点是空,就直接添加
        if (root==null){
            root=node;
        }else {
            root.add(node);
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (root!=null){
            root.zhongprintf();
        }else {
            System.out.println("当前平衡二叉树为空,不能遍历");
        }
    }
}
遍历平衡二叉树
Node{value=3}
Node{value=4}
Node{value=5}
Node{value=6}
Node{value=7}
Node{value=8}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2


四、AVL树右旋转
在这里插入图片描述

package com.ws.数据结构..平衡二叉树AVL.右旋转;

public class AVLTree {
    public static void main(String[] args) {
        //int[] arr={4,3,6,5,7,8};
        int[] arr={10,12,8,9,7,6};
        //创建平衡二叉树对象
        AVL avl=new AVL();
        //添加节点
        for (int i=0;i<arr.length;i++){
            avl.add(new Node(arr[i]));
        }
        //遍历平衡二叉树
        System.out.println("遍历平衡二叉树");
        avl.zhongprintf();

        System.out.println("旋转之后");
        System.out.println("树的高度="+avl.getRoot().height());//4
        System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//3
        System.out.println("右子树的高度="+avl.getRoot().youHeight());//1
        System.out.println("当前根节点="+avl.getRoot());//8


    }
}

//创建节点
class Node{
    int value;
    Node zuo;
    Node you;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    //添加节点
    //递归形式添加平衡二叉排序树
    public void add(Node node){
        if (node==null){
            return;
        }
        //判断传入节点值和子树的根节点的值的关系
        if (node.value<this.value){
            //小于  当前树左子节点为空,就直接挂上
            if (this.zuo==null){
                this.zuo=node;
            }else {
                //递归左子树添加
                this.zuo.add(node);
            }
        }else {
            //大于 当前右子节点为空,就直接挂上
            if (this.you==null){
                this.you=node;
            }else {
                //递归向右子树添加
                this.you.add(node);
            }
        }

        //当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
        if (youHeight()-zuoHeight()>1){
            zuoRotate();//左旋转
        }

        //当添加完一个节点后(左子树高度-右子树高度)>1就进行右旋转
        if (zuoHeight()-youHeight()>1){
            youRotate();//右旋转
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (this.zuo!=null){
            this.zuo.zhongprintf();
        }
        System.out.println(this);
        if (this.you!=null){
            this.you.zhongprintf();
        }
    }

    //返回当前节点的高度 以该节点为根节点的树的高度
    public int height(){
        return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
    }

    //返回左子树的额高度
    public int zuoHeight(){
        if (zuo==null){
            return 0;
        }
        return zuo.height();
    }

    //返回右子树的高度
    public int youHeight(){
        if (you==null){
            return 0;
        }
        return you.height();
    }

    //左旋转
    private void zuoRotate(){
        //创建新的节点,值是当前节点
        Node newNode=new Node(value);
        //把新的节点的左子树设置成当前节点的左子树
        newNode.zuo=zuo;
        //把新节点的右子树设置成当前节点的右子树的左子树
        newNode.you=you.zuo;
        //把当前节点的值换成右子树的值
        value=you.value;
        //把当前节点的右子树设置成当前节点的右子树的右子树
        you=you.you;
        //把当前节点的左子节点设置成新的节点
        zuo=newNode;
    }

    //右旋转
    private void youRotate(){
        //创建新的节点,值是当前节点
        Node newNode=new Node(value);
        //把新节点的右子树设置成当前节点的右子树
        newNode.you=you;
        //把新节点的左子节点指向当前节点的左子节点的右子节点
        newNode.zuo=zuo.you;
        //把当前节点的值改成左子节点的值
        value=zuo.value;
        //把当前节点的左子节点指向左子节点的左子节点
        zuo=zuo.zuo;
        //当前节点的右子节点指向新节点
        you=newNode;
    }

}

//创建AVL树
class AVL{
    private Node root;

    public Node getRoot() {
        return root;
    }

    //添加节点方法
    public void add(Node node){
        //根节点是空,就直接添加
        if (root==null){
            root=node;
        }else {
            root.add(node);
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (root!=null){
            root.zhongprintf();
        }else {
            System.out.println("当前平衡二叉树为空,不能遍历");
        }
    }
}
遍历平衡二叉树
Node{value=6}
Node{value=7}
Node{value=8}
Node{value=9}
Node{value=10}
Node{value=12}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2
当前根节点=Node{value=8}



五、AVL树双旋转
在这里插入图片描述

package com.ws.数据结构..平衡二叉树AVL.双旋转;

public class AVLTree {
    public static void main(String[] args) {
        //int[] arr={4,3,6,5,7,8};
        int[] arr={10,12,8,9,7,6};
        //创建平衡二叉树对象
        AVL avl=new AVL();
        //添加节点
        for (int i=0;i<arr.length;i++){
            avl.add(new Node(arr[i]));
        }
        //遍历平衡二叉树
        System.out.println("遍历平衡二叉树");
        avl.zhongprintf();

        System.out.println("旋转之后");
        System.out.println("树的高度="+avl.getRoot().height());//4
        System.out.println("左子树的高度="+avl.getRoot().zuoHeight());//3
        System.out.println("右子树的高度="+avl.getRoot().youHeight());//1
        System.out.println("当前根节点="+avl.getRoot());//8


    }
}

//创建节点
class Node{
    int value;
    Node zuo;
    Node you;

    public Node(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Node{" +
                "value=" + value +
                '}';
    }

    //添加节点
    //递归形式添加平衡二叉排序树
    public void add(Node node){
        if (node==null){
            return;
        }
        //判断传入节点值和子树的根节点的值的关系
        if (node.value<this.value){
            //小于  当前树左子节点为空,就直接挂上
            if (this.zuo==null){
                this.zuo=node;
            }else {
                //递归左子树添加
                this.zuo.add(node);
            }
        }else {
            //大于 当前右子节点为空,就直接挂上
            if (this.you==null){
                this.you=node;
            }else {
                //递归向右子树添加
                this.you.add(node);
            }
        }

        //当添加完节点后,如果(右子树的高度-左子树的高度)>1就进行旋转(左旋转)(avl树的特点)
        if (youHeight()-zuoHeight()>1){
            //如果它的右子树的左子树的高度大于他的右子树的右子树的高度
            if (you!=null&&you.zuoHeight()>you.youHeight()){
                //先进行对右子节点右旋转
                you.youRotate();
                // 再对当前节点进行左旋转
                zuoRotate();
            }else {
                //直接进行左旋转
                zuoRotate();//左旋转
            }
            return;//平衡后立马返回,要不会进入下一个if
        }

        //当添加完一个节点后(左子树高度-右子树高度)>1就进行右旋转
        if (zuoHeight()-youHeight()>1){
            //如果他左子树的右子树的高度大于他左子树的高度
            if (zuo!=null&&zuo.you.youHeight()>zuo.zuoHeight()){
                //先对左子树左旋转
                zuo.zuoRotate();
                //再对当前节点进行右旋转
                youRotate();
            }else {
                //直接进行右旋转即可
                youRotate();//右旋转
            }
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (this.zuo!=null){
            this.zuo.zhongprintf();
        }
        System.out.println(this);
        if (this.you!=null){
            this.you.zhongprintf();
        }
    }

    //返回当前节点的高度 以该节点为根节点的树的高度
    public int height(){
        return Math.max(zuo==null?0:zuo.height(),you==null?0:you.height())+1;
    }

    //返回左子树的额高度
    public int zuoHeight(){
        if (zuo==null){
            return 0;
        }
        return zuo.height();
    }

    //返回右子树的高度
    public int youHeight(){
        if (you==null){
            return 0;
        }
        return you.height();
    }

    //左旋转
    private void zuoRotate(){
        //创建新的节点,值是当前节点
        Node newNode=new Node(value);
        //把新的节点的左子树设置成当前节点的左子树
        newNode.zuo=zuo;
        //把新节点的右子树设置成当前节点的右子树的左子树
        newNode.you=you.zuo;
        //把当前节点的值换成右子树的值
        value=you.value;
        //把当前节点的右子树设置成当前节点的右子树的右子树
        you=you.you;
        //把当前节点的左子节点设置成新的节点
        zuo=newNode;
    }

    //右旋转
    private void youRotate(){
        //创建新的节点,值是当前节点
        Node newNode=new Node(value);
        //把新节点的右子树设置成当前节点的右子树
        newNode.you=you;
        //把新节点的左子节点指向当前节点的左子节点的右子节点
        newNode.zuo=zuo.you;
        //把当前节点的值改成左子节点的值
        value=zuo.value;
        //把当前节点的左子节点指向左子节点的左子节点
        zuo=zuo.zuo;
        //当前节点的右子节点指向新节点
        you=newNode;
    }

}

//创建AVL树
class AVL{
    private Node root;

    public Node getRoot() {
        return root;
    }

    //添加节点方法
    public void add(Node node){
        //根节点是空,就直接添加
        if (root==null){
            root=node;
        }else {
            root.add(node);
        }
    }

    //中序遍历
    public void zhongprintf(){
        if (root!=null){
            root.zhongprintf();
        }else {
            System.out.println("当前平衡二叉树为空,不能遍历");
        }
    }
}
遍历平衡二叉树
Node{value=6}
Node{value=7}
Node{value=8}
Node{value=9}
Node{value=10}
Node{value=12}
旋转之后
树的高度=3
左子树的高度=2
右子树的高度=2
当前根节点=Node{value=8}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值