avTree树java实现

本文详细介绍了如何使用Java实现AVL树,重点在于左旋和右旋操作,以保持树的平衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要实现思路为左旋转和右旋转
代码

package com.atguigu.avlTreeDemo;


import java.util.Objects;

/**
 * avl树:平衡二叉树
 */
public class AvlTreeDemo {
    public static void main(String[] args) {

        //左旋转测试开始
      /*  int[] arr = {4,3,6,5,7,8};
        AvlTree avlTree = new AvlTree();
        for (int num:arr) {
            avlTree.add(new Node(num));
        }
        System.out.println("树的前序遍历结果为");
        avlTree.infixOrder();
        System.out.println("根节点为" + avlTree.root);
        System.out.println("树的高度为" + avlTree.hight());
        System.out.println("树的左子树高度为" + avlTree.leftHight());
        System.out.println("树的右子树高度为" + avlTree.rightHight());*/
        //左旋转测试结束

        /*//右旋转测试开始
        int[] rightRotate = {10,12,8,9,7,6};
        AvlTree rightTree = new AvlTree();
        for (int num:rightRotate) {
            rightTree.add(new Node(num));
        }
        System.out.println("右旋转测试数的中序遍历结果为");
        rightTree.infixOrder();
        System.out.println("树的根节点为" + rightTree.root + "\n树的高度为" + rightTree.hight() +
                "\n树的左子树的高度为" +rightTree.leftHight() + "\n树的右子树的高度为" + rightTree.rightHight());
        //右旋转测试结束*/
        //双旋转测试开始
        int[] rightRotate = {10,11,7,6,8,9};
        AvlTree rightTree = new AvlTree();
        for (int num:rightRotate) {
            rightTree.add(new Node(num));
        }
        System.out.println("右旋转测试数的中序遍历结果为");
        rightTree.infixOrder();
        System.out.println("树的根节点为" + rightTree.root + "\n树的高度为" + rightTree.hight() +
                "\n树的左子树的高度为" +rightTree.leftHight() + "\n树的右子树的高度为" + rightTree.rightHight());

        //双旋转测试结束
    }
}

/**
 * 平衡二叉树的主体
 */
class AvlTree{
    public Node root;

    public AvlTree() {
    }

    public AvlTree(Node root) {
        this.root = root;
    }

    /**
     *     此方法为左旋转的方法
     *     步骤:
     *     1、创建一个新的节点:值为根节点的值
     *     2、新节点的右子节点为根节点的右节点的左节点
     *     3、新节点的左子节点为根节点的左节点
     *     4、将根节点的右节点的值赋值给根节点
     *     5、根节点的右节点为右节点的右节点
     *     6、根节点的左节点为新节点
     */
    public void leftRotate(){
        if (root == null){
            return;
        }
       root.leftRotate();
    }
    //添加节点
    public void add(Node node){
        if (root == null) {
            root = node;
        } else {
            root.add(node);
        }
    }
    //树的高度
    public int hight(){
        return root == null?0:root.hight();
    }
    //树的左子树的高度
    public int leftHight(){
        return root == null?0:root.leftHight();
    }
    //树的左子树的高度
    public int rightHight(){
        return root == null?0:root.righttHight();
    }
    //删除节点
    public void del(int values){
        //查看待删除的节点是否存在
        if (searchNode(values) == null){
            System.out.println("待删除的节点不存在");
        }else {
            Node delNode = searchNode(values);//寻找到待删除的节点
            Node parent = searchParent(values);
            boolean flag1 = (delNode.left != null);
            boolean flag2 = (delNode.right != null);
            boolean flagpar = !(parent == null);
            Node temp;
            if (!flag1 && !flag2){//如果待删除的节点是叶子结点,没有子节点
                if (parent == null){//待删除的是根节点
                    root =null;
                }else {//有父节点
                    if (parent.left != null && parent.left.equals(delNode)){
                        parent.left = null;
                    }else if (parent.right != null && parent.right.values == values){
                        parent.right = null;
                    }
                }
            }else if ( (flag1 && !flag2 )//如果删除的节点有一个子节点
                    ||(!flag1 && flag2)){//只有一个子节点
                if (flag1 && !flagpar){//没有父节点且左边有一个子节点,即根节点
                    root = delNode.left;
                    /*delNode.left = null;
                    delNode = temp;*/
                }else if (flag1 && flagpar){//有父节点且左边有一个子节点
                    if (parent.left != null && parent.left.values == values){//目标节点是父节点的左子节点
                        parent.left = delNode.left;
                    }else if (parent.right != null && parent.right.values == values){//目标节点是父节点的左子节点
                        parent.right = delNode.left;
                    }
                }else if (flag2 && !flagpar){//没有父节点且右边有一个子节点,即根节点
                    root = delNode.right;
                    /*delNode.right = null;
                    delNode = temp;*/
                }else if (flag2 && flagpar){//有父节点且右边有一个子节点
                    if (parent.left != null && parent.left.values == values){//目标节点是父节点的左子节点
                        parent.left = delNode.right;
                    }else if (parent.right != null && parent.right.values == values){//目标节点是父节点的左子节点
                        parent.right = delNode.right;
                    }
                }
            }else if (flag1 && flag2){//如果待删除的节点有两个子节点
               /* temp = delNode.right.fingMin();//法一:从右边寻找最小的
                del(delNode.right.fingMin().values);
                delNode.values = temp.values;*/
                //法二:从左边找最大的
                temp = delNode.left.fingMax();
                del(delNode.left.fingMax().values);
                delNode.values = temp.values;
            }
        }

    }
    //查找等待删除的节点是否存在
    public Node searchNode(int values){
        if (root.values == values){
            return root;
        }else{
            return root.search(values);
        }
    }
    //查找待删除的节点的父节点
    public Node searchParent(int values){
        if (root.values == values){
            return null;
        }else {
            return root.searchParents(values);
        }
    }
    //中序遍历
    public void infixOrder(){
        if (root == null){
            System.out.println("空树");
        }else{
            root.infixOrder();
        }
    }
}
/**
 * 节点
 */
class Node{
    public int values;//节点对应的值
    Node left;//左子节点
    Node right;//右子节点

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Node node = (Node) o;
        return values == node.values;
    }

    /**
     * 左旋转的方法
     * 步骤:
     *    1、创建一个新节点(值为当前节点)
     *    2、 新节点左节点为原来的左节点
     *    3、新节点的右节点为原来右节点的左节点
     *    4、原来左节点连接新节点
     *    5、原来节点值为原右节点值
     *    6、原来右节点为右节点的右节点
     */
    public void leftRotate(){
        Node newNode = new Node(values);
        newNode.left = left;
        newNode.right = right.left;
        left = newNode;
        this.values = right.values;
        right = right.right;
    }

    /**
     * 右旋转的方法
     * 1、创建新节点(值为当前节点)
     * 2、新节点右节点为当前节点的右节点
     * 3、新节点左节点为当前左节点的右节点
     * 4、当前节点值改为左节点的值
     * 5、当前右节点为新节点
     * 6、当前左节点为左节点的左节点
     */
    public void rightRotate(){
        Node newNode = new Node(values);
        newNode.right = right;
        newNode.left =left.right;
        this.values = left.values;
        right = newNode;
        left = left.left;
    }
    //得到以该节点为根节点的子树的高度
    public int hight(){
        return Math.max((left == null? 1: left.hight() + 1),
                (right == null? 1:right.hight() +1));
    }
    //得到该节点的左子树的子树高度
    public int leftHight(){
        return (left == null)? 0: left.hight();
    }
    //得到该节点的右子树的子树高度
    public int righttHight(){
        return (right == null)? 0: right.hight();
    }
    //寻找一个节点下面的最小的节点
    public Node  fingMin(){
        if (this.left == null ){
            return this;
        }else {
            return this.left.fingMin();
        }
    }
    //寻找一个节点下面的最大的节点
    public Node fingMax(){
        if (this.right == null ){
            return this;
        }else {
            return this.right.fingMax();
        }
    }
    @Override
    public int hashCode() {

        return Objects.hash(values);
    }



    //查找待删除的节点是否存在
    public Node search(int values){
        if (this.values == values){
            return this;
        }else if (this.left != null && this.values > values){
            return this.left.search(values);
        }else if (this.right != null && this.values <= values){
            return this.right.search(values);
        }else {
            return null;
        }
    }
    //查找待删除节点的父节点
    public Node searchParents(int values){
        if (this.values == values){
            return null;
        }
        if ((this.left != null && this.left.values == values) ||
                this.right != null && this.right.values == values ){
            return this;
        }else if (this.left != null && this.values > values){
            return this.left.searchParents(values);
        }else if (this.right != null && this.values <= values){
            return this.right.searchParents(values);
        }else {
            return null;
        }
    }
    public Node(Node left) {
        this.left = left;
    }

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

    //中序遍历
    public void infixOrder(){
        if (this.left != null){
            this.left.infixOrder();
        }
        System.out.println(this);
        if (this.right != null){
            this.right.infixOrder();
        }
    }
    //添加节点的方法
    public void add(Node node){
        if (node == null){
            return;
        }else{
            if (node.values < this.values){
                if (this.left == null){
                    this.left = node;
                }else{
                    this.left.add(node);
                }
            }else{
                if ((this.right == null)) {
                    this.right = node;
                } else {
                    this.right.add(node);
                }
            }
            if (righttHight() - leftHight() > 1){//当添加完一个节点后,右子树的高度比左子树高出超过1以及以上,进行左旋转
                if (right != null && right.leftHight() > right.righttHight()){
                    right.leftRotate();
                }
                leftRotate();
            }else if (leftHight() - righttHight() > 1){//当添加完一个节点后,左子树的高度比左子树高出超过1以及以上,进行右旋转
                if (left != null && left.righttHight() > left.leftHight()){
                    left.leftRotate();
                }
                rightRotate();
            }
        }
    }
    @Override
    public String toString() {
        return "Node{" +
                "values=" + values +
                '}';
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值