arbre de recherche binaire auto-équilibré d'AVL

Arbre de recherche binaire à équilibrage Slef

Un arbre binaire équilibré, tout d'abord, est un arbre de tri binaire (Binary Sort Tree), qui est une optimisation de BST.

introduction de base

L'arbre de recherche binaire équilibré est également appelé arbre de recherche binaire équilibré (arbre de recherche binaire d'équilibrage Slef), également appelé arbre AVL, qui peut garantir une efficacité de requête élevée.

Fonctionnalités

C'est un arbre vide ou la valeur absolue de la différence de hauteur entre ses sous-arbres gauche et droit ne dépasse pas 1, et les sous-arbres gauche et droit sont tous deux un arbre binaire équilibré.

Implémentation couramment utilisée

Arbre rouge-noir, AVL, arbre bouc émissaire, Treap, arbre extensible, etc.

Tourne à gauche

1. Créez un nouveau nœud newNode

2.newNode.left = gauche

3.newNode.right = right.left

4.valeur = right.value

5.droite = droite.droite

6. gauche = newLeft

Double rotation

Parfois, une seule rotation ne résout pas le problème, il y a donc une 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();
        }
    }
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_41729287/article/details/113612489
conseillé
Classement