self-balancing binary search tree Of AVL

Slef-balancing binary search tree

A balanced binary tree, first of all, is a binary sort tree (Binary Sort Tree), which is an optimization of BST.

basic introduction

Balanced binary search tree is also called balanced binary search tree (Slef-balancing binary search tree), also called AVL tree, which can ensure high query efficiency

Features

It is an empty tree or the absolute value of the height difference between its left and right subtrees does not exceed 1, and the left and right subtrees are both a balanced binary tree.

Commonly used implementation

Red-black tree, AVL, scapegoat tree, Treap, stretch tree, etc.

Rotate left

1. Create a new node newNode

2.newNode.left =left

3.newNode.right=right.left

4.value = right.value

5.right=right.right

6.left=newLeft

Double rotation

Sometimes a single rotation does not solve the problem; so there is a double rotation.

package com.algorthm.tree.selfBalanceBinarySearchTree;

public class AVKTreeDemo {
    
    
    public static void main(String[] args) {
    
    
        int [] arr ={
    
    4,3,6,5,7,8};

        AVLTree avlTree = new AVLTree();

        for (int i = 0; i < arr.length; i++) {
    
    
            avlTree.add(new Node(arr[i]));
        }

        //遍历
        System.out.println("infixOrder");
        avlTree.infixOrder();
        System.out.println("树的高度:"+avlTree.getRoot().height());//4
        System.out.println("左子树的高度"+avlTree.getRoot().leftHeight());//1
        System.out.println("右子树的高度"+avlTree.getRoot().rightHeight());//3
        System.out.println("当前的根结点"+avlTree.getRoot());
    }
}

class AVLTree {
    
    
    private Node root;


    public Node getRoot(){
    
    
        return root;
    }

    public Node search(int value) {
    
    
        if (root == null) {
    
    
            return null;
        }else{
    
    
            return root.search(value);
        }
    }

    public Node searchParent(int value){
    
    
        if(root==null){
    
    
            return null;
        }else{
    
    
            return root.searchParent(value);
        }
    }

    public int delRightTreeMin(Node node){
    
    
        Node target=node;
        while(target.left!=null){
    
    
            target = target.left;
        }
        delNode(target.value);
        return target.value;
    }
    public int delLeftTreeMax(Node node){
    
    
        Node target=node;
        while(target.right!=null){
    
    
            target=target.right;
        }
        delNode(target.value);
        return target.value;
    }

    public void delNode(int value){
    
    
        if(root == null){
    
    
            return ;
        }else{
    
    
            Node target = this.search(value);

            if(target==null){
    
    
                return;
            }
            if(root.left==null&& root.right==null){
    
    
                root=null;
                return;
            }

            Node parent = searchParent(value);
            if(target.left==null && target.right==null){
    
    

            }else if(target.left!=null && target.right!=null){
    
    
                int minValue= delRightTreeMin(target);
                target.value=minValue;
            }else{
    
    
                if(target.left!=null){
    
    
                    if(parent!=null){
    
    
                        if(parent.left.value== target.value){
    
    
                            parent.left=target.left;
                        }
                        if(parent.right.value== target.value){
    
    
                            parent.right=target.left;
                        }
                    }
                }
                if(target.right!=null){
    
    
                    if(parent!=null){
    
    
                        if(parent.left.value== target.value){
    
    
                            parent.left=target.right;
                        }
                        if(parent.right.value== target.value){
    
    
                            parent.right=target.right;
                        }
                    }
                }
            }
        }
    }

    public void add(Node node){
    
    
        if(root ==null){
    
    
            root=node;
        }else{
    
    
            root.add(node);
        }
    }

    public  void infixOrder(){
    
    
        if(root!=null){
    
    
            root.infixOrder();
        }else{
    
    
            System.out.println("the tree is empty");
        }
    }

}

class Node {
    
    
    int value;
    Node left;
    Node right;


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

    //返回左子树的高度
    public int leftHeight() {
    
    
        if (left == null) {
    
    
            return 0;
        } else {
    
    
            return left.height();
        }
    }

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

    //左旋转 为了降低右子树的高度
    private void leftRotate(){
    
    
        //1.创建新的节点,以当前跟结点的值
        Node newNode = new Node(value);
        //2.把新节点的左子树设置为当前结点的左子树
        newNode.left=left;
        //3.把新节点的右子树设置成当前结点的右子树的左子树
        newNode.right=right.left;
        //4.把当前结点的值替换成右子树的值
        value=right.value;
        //5.把当前结点的右子树设置为右子树的右子树
        right=right.right;
        //6.把当前结点的左子树(左子节点)设置成新的结点
        left=newNode;
    }

    //右旋转 为了降低左子树的高度
    private void rightRotate(){
    
    
        Node newNode = new Node(value);
        //1.
        newNode.right=right;
        //2.
        newNode.left=left.right;
        //3.
        value=left.value;
        //4.
        left=left.left;
        //5.
        right=newNode;
    }

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

    public Node search(int value) {
    
    
        if (value == this.value) {
    
    
            return this;
        } else if (value < this.value) {
    
    
            if (this.left == null) {
    
    
                return null;
            }
            return this.left.search(value);
        } else {
    
    
            if (this.right == null) {
    
    
                return null;
            }
            return this.right.search(value);
        }
    }

    public Node searchParent(int value) {
    
    
        if ((this.left != null && this.left.value == value) ||
                this.right != null && this.right.value == value) {
    
    
            return this;
        } else {
    
    
            if (value < this.value && this.left != null) {
    
    
                return this.left.searchParent(value);
            } else if (value >= this.value && this.right != null) {
    
    
                return this.right.searchParent(value);
            } else {
    
    
                return null;
            }
        }
    }

    @Override
    public String toString() {
    
    
        return "Node [ value " + value + " ]";
    }

    public void add(Node node) {
    
    
        if (node == null) {
    
    
            return;
        }
        if (node.value < this.value) {
    
    
            if (this.left == null) {
    
    
                this.left = node;
            } else {
    
    
                this.left.add(node);
            }
        }
        if (node.value > this.value) {
    
    
            if (this.right == null) {
    
    
                this.right = node;
            } else {
    
    
                this.right.add(node);
            }
        }

        //当添加完一个结点后,(右子树的高度 - 左子树的高度) >1, 左旋转----降低右子树的高度
        if(rightHeight() -leftHeight() >1){
    
    
            //如果它的右子树的左子树的高度 大于 它的右子树的高度
            if(right!=null && right.leftHeight()> right.rightHeight()){
    
    
                //1.先对右子节点进行右旋转
                right.rightRotate();
                //然后再对当前结点进行左旋转
                leftRotate();
            }else{
    
    
                //直接左旋转
                leftRotate();//左旋转
            }
            return;//避免不必要的比较
        }

        //当添加完一个节点,(左子树高度 - 右子树高度) >1 ,右旋转----降低左子树的高度
        if(leftHeight()-rightHeight() >1){
    
    
            //如果当前的左子树的右子树高度大于它的左子树高度
            if(left !=null &&left.rightHeight() >left.leftHeight()){
    
    
                //1.先对当前结点的左节点(左子树)->左旋转
                left.leftRotate();
                //再对当结点进行右旋转
                rightRotate();
            }else{
    
    
                //直接进行右旋转接口
                rightRotate();
            }
        }
    }

    public void infixOrder() {
    
    
        if (this.left != null) {
    
    
            this.left.infixOrder();
        }
        System.out.println(this);
        if (this.right != null) {
    
    
            this.right.infixOrder();
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_41729287/article/details/113612489