java实现二叉平衡树

2022/4/21 20:42:43

本文主要是介绍java实现二叉平衡树,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. java 实现二叉平衡树

/**
 *  二叉平衡树
 *  规则:
 *      1.新节点默认的深度为1
 *      2.左子树和右子树高度相差超过1 就是不平衡,需要进行旋转操作
 *          右旋操作
 *          2.1 如果左左节点比左右节点高,那要先对左节点左旋,再对当前节点右旋。否则直接当前节点右旋。
 *          左旋操作
 *          2.2 如果右左节点高于右右节点,需要先对右点节点右旋,再对当前节点左旋。否则直接当前节点左旋。
 *
 */

public class MyAVLTree {
    Integer data;   // 数据
    Integer depth;  // 深度  初始时默认为1
    MyAVLTree leftChild;  // 左子树
    MyAVLTree rightChild;  // 右子树
    MyAVLTree parent;    // 父子树

    public MyAVLTree(Integer data) {
        this.data = data;
        this.depth = 1;
    }

    // 增
    public void insert(MyAVLTree newMyAVLTree) {
        if (newMyAVLTree.data == data) {
            return;
        }
        // 插入左边
        if (data > newMyAVLTree.data) {
            if (leftChild == null) {
                leftChild = newMyAVLTree;
                newMyAVLTree.parent = this;
            } else {
                leftChild.insert(newMyAVLTree);
            }
        } else{
            // 插入右边
            if (rightChild == null) {
                rightChild = newMyAVLTree;
                newMyAVLTree.parent = this;
            } else {
                rightChild.insert(newMyAVLTree);
            }
        }
        // 调节平衡
        adjustBalenced(newMyAVLTree);
    }

    // 调整平衡
    private void adjustBalenced(MyAVLTree newMyAVLTree) {
        newMyAVLTree.depth = getDepth(newMyAVLTree) ;


        // 父节点左子树和右子树深度对比,如果平衡,则再递归检查父
        if (checkedBalanced(newMyAVLTree)) {
            // null是根节点
            if (newMyAVLTree.parent == null) {
                return;
            }
            adjustBalenced(newMyAVLTree.parent);
            return;
        }

        // 1.如果左左节点比左右节点高,那要先对左节点左旋,再对当前节点右旋。否则直接当前节点右旋。
        if (getDepth(newMyAVLTree.leftChild) > getDepth(newMyAVLTree.rightChild)) {
            //
            if (getDepth(newMyAVLTree.leftChild.leftChild) < getDepth(newMyAVLTree.leftChild.rightChild)) {
                leftRevolve(newMyAVLTree.leftChild);
                rightRevolve(newMyAVLTree);
            } else {
                rightRevolve(newMyAVLTree);
            }
            adjustBalenced(newMyAVLTree);
            return;
        }
        // 如果右左节点高于右右节点,需要先对右点节点右旋,再对当前节点左旋。否则直接当前节点左旋。
        if (getDepth(newMyAVLTree.leftChild) < getDepth(newMyAVLTree.rightChild)) {
            if (getDepth(newMyAVLTree.rightChild.leftChild) > getDepth(newMyAVLTree.rightChild.rightChild)) {
                rightRevolve(newMyAVLTree.rightChild);
                leftRevolve(newMyAVLTree);
            } else {
                leftRevolve(newMyAVLTree);
            }
            adjustBalenced(newMyAVLTree);
        }
    }

    // 右旋
    private void rightRevolve(MyAVLTree newMyAVLTree) {
        final MyAVLTree parent = newMyAVLTree.parent;
        final MyAVLTree leftChild = newMyAVLTree.leftChild;
        if (parent != null) {
            parent.rightChild = leftChild;
        }
        newMyAVLTree.parent = leftChild;
        newMyAVLTree.leftChild = newMyAVLTree.leftChild.rightChild;
        newMyAVLTree.depth = getDepth(newMyAVLTree);
        leftChild.parent = parent;
        leftChild.rightChild = newMyAVLTree;
        leftChild.depth = getDepth(leftChild) ;

    }
    // 左旋
    private void leftRevolve(MyAVLTree myAVLTree) {
        MyAVLTree right = myAVLTree.rightChild;
        final MyAVLTree parent = myAVLTree.parent;

        if (parent != null) {
            parent.leftChild = right;
        }
        myAVLTree.parent = right;
        myAVLTree.rightChild = myAVLTree.rightChild.leftChild;
        myAVLTree.depth = getDepth(myAVLTree);
        right.parent = parent;
        right.leftChild = myAVLTree;
        right.depth = getDepth(right) ;
    }

    // 检查节点的左右子树是否平衡
    private boolean checkedBalanced(MyAVLTree myAVLTree) {
        return Math.abs(getDepth(myAVLTree.leftChild) - getDepth(myAVLTree.rightChild)) <=1;
    }

    // 得出节点的深度
    private Integer getDepth(MyAVLTree newMyAVLTree) {
        if (newMyAVLTree == null) {
            return 1;
        }
        MyAVLTree left = newMyAVLTree.leftChild;
        MyAVLTree right = newMyAVLTree.rightChild;

        if (left == null && right == null) {
            return 1;
        }
        if (left == null && right != null) {
            return right.depth + 1;
        }
        if (left != null && right == null) {
            return left.depth + 1;
        }
        return left.depth > right.depth ? left.depth + 1 : right.depth + 1;
    }

    // 查找root 节点
    public MyAVLTree getRoot() {
        if (parent == null) {
            return this;
        }
        return parent.getRoot();
    }
    // 当前节点是否为父节点
    private Boolean isRoot(MyAVLTree myAVLTree) {
        return myAVLTree.parent == null;
    }

    // 删
    public Boolean del(Integer integer) {
        if (integer == null) {
            return false;
        }
        MyAVLTree delAVLTree = this.find(integer);
        if (delAVLTree == null) {
            return false;
        }

        MyAVLTree delParent = delAVLTree.parent;
        MyAVLTree left = delAVLTree.leftChild;
        MyAVLTree right = delAVLTree.rightChild;

        // 左右都没
        if (left == null && right == null) {
            if (delParent == null) {
                // 即当前树仅一个节点,且删除的就是这个节点
                return true;
            }
            if (delAVLTree.equals(delParent.leftChild)) {
                delParent.leftChild = null;
            } else {
                delParent.rightChild = null;
            }
            adjustBalenced(delParent);
            return true;
        }
        // 左没 右有
        if (left == null && right != null) {
            if (delParent == null) {
                right.parent = null;
                return true;
            }
            delParent.rightChild = right;
            adjustBalenced(right);
            return true;
        }
        // 左没 右有
        if (left != null && right == null) {
            if (delParent == null) {
                left.parent = null;
                return true;
            }
            delParent.leftChild = left;
            adjustBalenced(left);
            return true;
        }
        // 两边都有
        final MyAVLTree rightTemp= left.rightChild;
        left.rightChild = right;
        left.parent = delParent;
        right.parent = left;
        if (rightTemp != null) {
            left.insert(rightTemp);
        } else {
            adjustBalenced(left);
        }
        return true;

    }

    // 查
    public MyAVLTree find(Integer value) {
        if (isRoot(this)) {
            findTree(value);
        }
        return getRoot().findTree(value);
    }
    // 从根节点开始查找元素
    private MyAVLTree findTree(Integer value) {
        if (this.data == value) {
            return this;
        }
        if (this.data > value && this.leftChild != null) {
            return this.leftChild.findTree(value);
        }
        if (this.data < value && this.rightChild != null) {
            return this.rightChild.findTree(value);
        }
        return null;
    }

}

 

有个缺点,不能删除自己

 



这篇关于java实现二叉平衡树的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程