• 二叉树AVL树04--[四种旋转&&添加修复&&删除修复]


    1.AVL树基本介绍

    1.1名字由来

     1.2AVL树属性

     1.3平衡对比

     1.4简单的继承结构

     1.5添加导致的失衡

     2.AVL树的四种旋转

    通过旋转来解决添加或删除导致AVL树失衡

    2.1LL-右旋转(单旋)

     

     2.2RR-左旋转(单旋)

    2.3RL-LL右旋转,RR左旋转(双旋)

    2.4LR-RR左旋转,LL右旋转(双旋)

     

    2.5旋转的别名

    3.添加导致失衡

    3.1添加之后的修复代码

        @Override
        protected void afterAdd(Node<E> node) {
            while ((node = node.parent) != null) {
                if (isBalanced(node)) {
                    // 更新高度
                    updateHeight(node);
                } else {
                    // 恢复平衡
                    rebalance(node);
                    // 整棵树恢复平衡
                    break;
                }
            }
        }
    /**
         * 恢复平衡
         * @param grand 高度最低的那个不平衡节点
         */
        @SuppressWarnings("unused")
        private void rebalance2(Node<E> grand) {
            Node<E> parent = ((AVLNode<E>)grand).tallerChild();
            Node<E> node = ((AVLNode<E>)parent).tallerChild();
            if (parent.isLeftChild()) { // L
                if (node.isLeftChild()) { // LL
                    rotateRight(grand);
                } else { // LR
                    rotateLeft(parent);
                    rotateRight(grand);
                }
            } else { // R
                if (node.isLeftChild()) { // RL
                    rotateRight(parent);
                    rotateLeft(grand);
                } else { // RR
                    rotateLeft(grand);
                }
            }
        }
        /**
         * 恢复平衡
         * @param grand 高度最低的那个不平衡节点
         */
        private void rebalance(Node<E> grand) {
            Node<E> parent = ((AVLNode<E>)grand).tallerChild();
            Node<E> node = ((AVLNode<E>)parent).tallerChild();
            if (parent.isLeftChild()) { // L
                if (node.isLeftChild()) { // LL
                    rotate(grand, node, node.right, parent, parent.right, grand);
                } else { // LR
                    rotate(grand, parent, node.left, node, node.right, grand);
                }
            } else { // R
                if (node.isLeftChild()) { // RL
                    rotate(grand, grand, node.left, node, node.right, parent);
                } else { // RR
                    rotate(grand, grand, parent.left, parent, node.left, node);
                }
            }
        }
    View Code

    旋转代码

    private void rotateLeft(Node<E> grand) {
            Node<E> parent = grand.right;
            Node<E> child = parent.left;
            grand.right = child;
            parent.left = grand;
            afterRotate(grand, parent, child);
        }
        
        private void rotateRight(Node<E> grand) {
            Node<E> parent = grand.left;
            Node<E> child = parent.right;
            grand.left = child;
            parent.right = grand;
            afterRotate(grand, parent, child);
        }
        
        private void afterRotate(Node<E> grand, Node<E> parent, Node<E> child) {
            // 让parent称为子树的根节点
            parent.parent = grand.parent;
            if (grand.isLeftChild()) {
                grand.parent.left = parent;
            } else if (grand.isRightChild()) {
                grand.parent.right = parent;
            } else { // grand是root节点
                root = parent;
            }
            
            // 更新child的parent
            if (child != null) {
                child.parent = grand;
            }
            
            // 更新grand的parent
            grand.parent = parent;
            
            // 更新高度
            updateHeight(grand);
            updateHeight(parent);
        }
    View Code

     3.2实例

    实例2

     3.3统一所有操作

     3.4统一所有旋转操作

    private void rotate(
                Node<E> r, // 子树的根节点
                Node<E> b, Node<E> c,
                Node<E> d,
                Node<E> e, Node<E> f) {
            // 让d成为这棵子树的根节点
            d.parent = r.parent;
            if (r.isLeftChild()) {
                r.parent.left = d;
            } else if (r.isRightChild()) {
                r.parent.right = d;
            } else {
                root = d;
            }
            
            //b-c
            b.right = c;
            if (c != null) {
                c.parent = b;
            }
            updateHeight(b);
            
            // e-f
            f.left = e;
            if (e != null) {
                e.parent = f;
            }
            updateHeight(f);
            
            // b-d-f
            d.left = b;
            d.right = f;
            b.parent = d;
            f.parent = d;
            updateHeight(d);
        }
    /**
         * 恢复平衡
         * @param grand 高度最低的那个不平衡节点
         */
        private void rebalance(Node<E> grand) {
            Node<E> parent = ((AVLNode<E>)grand).tallerChild();
            Node<E> node = ((AVLNode<E>)parent).tallerChild();
            if (parent.isLeftChild()) { // L
                if (node.isLeftChild()) { // LL
                    rotate(grand, node, node.right, parent, parent.right, grand);
                } else { // LR
                    rotate(grand, parent, node.left, node, node.right, grand);
                }
            } else { // R
                if (node.isLeftChild()) { // RL
                    rotate(grand, grand, node.left, node, node.right, parent);
                } else { // RR
                    rotate(grand, grand, parent.left, parent, node.left, node);
                }
            }
        }
    View Code

    3.5独立AVLNode

    4.删除导致失衡

    4.1实例

    4.2LL-右旋转(单旋)

    4.3RR-左旋转(单旋)

    4.4LR-RR左旋转,LL右旋转(双旋)

    4.5RL-LL右旋转,RR左旋转(双旋)

    4.5删除之后的修复

     5.总结

    6.AVL树代码总结

    package com.mj.tree;
    
    import java.util.Comparator;
    
    public class AVLTree<E> extends BST<E> {
        public AVLTree() {
            this(null);
        }
        
        public AVLTree(Comparator<E> comparator) {
            super(comparator);
        }
        
        @Override
        protected void afterAdd(Node<E> node) {
            while ((node = node.parent) != null) {
                if (isBalanced(node)) {
                    // 更新高度
                    updateHeight(node);
                } else {
                    // 恢复平衡
                    rebalance(node);
                    // 整棵树恢复平衡
                    break;
                }
            }
        }
        
        @Override
        protected void afterRemove(Node<E> node) {
            while ((node = node.parent) != null) {
                if (isBalanced(node)) {
                    // 更新高度
                    updateHeight(node);
                } else {
                    // 恢复平衡
                    rebalance(node);
                }
            }
        }
        
        @Override
        protected Node<E> createNode(E element, Node<E> parent) {
            return new AVLNode<>(element, parent);
        }
        
        /**
         * 恢复平衡
         * @param grand 高度最低的那个不平衡节点
         */
        @SuppressWarnings("unused")
        private void rebalance2(Node<E> grand) {
            Node<E> parent = ((AVLNode<E>)grand).tallerChild();
            Node<E> node = ((AVLNode<E>)parent).tallerChild();
            if (parent.isLeftChild()) { // L
                if (node.isLeftChild()) { // LL
                    rotateRight(grand);
                } else { // LR
                    rotateLeft(parent);
                    rotateRight(grand);
                }
            } else { // R
                if (node.isLeftChild()) { // RL
                    rotateRight(parent);
                    rotateLeft(grand);
                } else { // RR
                    rotateLeft(grand);
                }
            }
        }
        /**
         * 恢复平衡
         * @param grand 高度最低的那个不平衡节点
         */
        private void rebalance(Node<E> grand) {
            Node<E> parent = ((AVLNode<E>)grand).tallerChild();
            Node<E> node = ((AVLNode<E>)parent).tallerChild();
            if (parent.isLeftChild()) { // L
                if (node.isLeftChild()) { // LL
                    rotate(grand, node, node.right, parent, parent.right, grand);
                } else { // LR
                    rotate(grand, parent, node.left, node, node.right, grand);
                }
            } else { // R
                if (node.isLeftChild()) { // RL
                    rotate(grand, grand, node.left, node, node.right, parent);
                } else { // RR
                    rotate(grand, grand, parent.left, parent, node.left, node);
                }
            }
        }
        
        private void rotate(
                Node<E> r, // 子树的根节点
                Node<E> b, Node<E> c,
                Node<E> d,
                Node<E> e, Node<E> f) {
            // 让d成为这棵子树的根节点
            d.parent = r.parent;
            if (r.isLeftChild()) {
                r.parent.left = d;
            } else if (r.isRightChild()) {
                r.parent.right = d;
            } else {
                root = d;
            }
            
            //b-c
            b.right = c;
            if (c != null) {
                c.parent = b;
            }
            updateHeight(b);
            
            // e-f
            f.left = e;
            if (e != null) {
                e.parent = f;
            }
            updateHeight(f);
            
            // b-d-f
            d.left = b;
            d.right = f;
            b.parent = d;
            f.parent = d;
            updateHeight(d);
        }
        
        private void rotateLeft(Node<E> grand) {
            Node<E> parent = grand.right;
            Node<E> child = parent.left;
            grand.right = child;
            parent.left = grand;
            afterRotate(grand, parent, child);
        }
        
        private void rotateRight(Node<E> grand) {
            Node<E> parent = grand.left;
            Node<E> child = parent.right;
            grand.left = child;
            parent.right = grand;
            afterRotate(grand, parent, child);
        }
        
        private void afterRotate(Node<E> grand, Node<E> parent, Node<E> child) {
            // 让parent称为子树的根节点
            parent.parent = grand.parent;
            if (grand.isLeftChild()) {
                grand.parent.left = parent;
            } else if (grand.isRightChild()) {
                grand.parent.right = parent;
            } else { // grand是root节点
                root = parent;
            }
            
            // 更新child的parent
            if (child != null) {
                child.parent = grand;
            }
            
            // 更新grand的parent
            grand.parent = parent;
            
            // 更新高度
            updateHeight(grand);
            updateHeight(parent);
        }
        
        private boolean isBalanced(Node<E> node) {
            return Math.abs(((AVLNode<E>)node).balanceFactor()) <= 1;
        }
        
        private void updateHeight(Node<E> node) {
            ((AVLNode<E>)node).updateHeight();
        }
        
        private static class AVLNode<E> extends Node<E> {
            int height = 1;
            
            public AVLNode(E element, Node<E> parent) {
                super(element, parent);
            }
            
            public int balanceFactor() {
                int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
                int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
                return leftHeight - rightHeight;
            }
            
            public void updateHeight() {
                int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
                int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
                height = 1 + Math.max(leftHeight, rightHeight);
            }
            
            public Node<E> tallerChild() {
                int leftHeight = left == null ? 0 : ((AVLNode<E>)left).height;
                int rightHeight = right == null ? 0 : ((AVLNode<E>)right).height;
                if (leftHeight > rightHeight) return left;
                if (leftHeight < rightHeight) return right;
                return isLeftChild() ? left : right;
            }
            
            @Override
            public String toString() {
                String parentString = "null";
                if (parent != null) {
                    parentString = parent.element.toString();
                }
                return element + "_p(" + parentString + ")_h(" + height + ")";
            }
        }
    }
    View Code
  • 相关阅读:
    tf.nn.batch_normalization()函数解析(最清晰的解释)
    tf.identity()函数解析(最清晰的解释)
    Github Fork项目后如何与源主机代码保持更新同步
    nginx平滑升级、在线添加模块(tengine 动态加载模块)
    nginx平滑升级、在线添加模块(tengine 动态加载模块)
    nginx平滑升级、在线添加模块(tengine 动态加载模块)
    nginx平滑升级、在线添加模块(tengine 动态加载模块)
    使用mysqldump自动备份数据库脚本
    使用mysqldump自动备份数据库脚本
    使用mysqldump自动备份数据库脚本
  • 原文地址:https://www.cnblogs.com/ggnbnb/p/12315755.html
Copyright © 2020-2023  润新知