【恋上数据结构与算法 第一季】AVL树 AVLTree


持续学习&持续更新中…


什么是AVL树

在这里插入图片描述

平衡因子

在这里插入图片描述

平衡对比

在这里插入图片描述

继承结构

在这里插入图片描述

添加导致的失衡

在这里插入图片描述

添加失衡解决方案

LL:右旋转(单旋)

在这里插入图片描述

RR:左旋转(单旋)

在这里插入图片描述

LR:先RR左旋转 后LL右旋转(双旋)

在这里插入图片描述

RL:先LL右旋转 后RR左旋转(双旋)

在这里插入图片描述

统一添加操作

在这里插入图片描述

添加过程示例

在这里插入图片描述

在这里插入图片描述

删除导致的失衡

在这里插入图片描述

删除失衡解决方案

LL:右旋转(单旋)

在这里插入图片描述

RR:左旋转(单旋)

在这里插入图片描述

LR:先RR左旋转 后LL右旋转(双旋)

在这里插入图片描述

RL:先LL右旋转 后RR左旋转(双旋)

在这里插入图片描述

代码实现

BinarySearchTree

package taught_by_mjlmj.tree;

/*
    二叉搜索树
 */

import java.util.Comparator;

public class BinarySearchTree<E> extends BinaryTree<E> {
    
    

    private Comparator<E> comparator;

    public BinarySearchTree() {
    
    
    }

    public BinarySearchTree(Comparator<E> comparator) {
    
    
        this.comparator = comparator;
    }

    @Override
    public void add(E element) {
    
    
        elementNotNullCheck(element);
        Node<E> newNode = createNewNode(element, null);
        if (null == root) {
    
    
            root = newNode;
        } else {
    
    
            Node<E> node = root;
            Node<E> parent = root;
            int cmp = 0;
            while (null != node) {
    
    
                parent = node;
                cmp = compare(element, node.element);
                if (cmp > 0) {
    
    
                    node = node.right;
                } else if (cmp < 0) {
    
    
                    node = node.left;
                } else {
    
    
                    /*
                        元素相等时建议更新元素
                    */
                    node.element = element;
                    return;
                }
            }

            newNode = createNewNode(element, parent);

            if (cmp > 0) {
    
    
                parent.right = newNode;
            } else {
    
     // cmp < 0
                parent.left = newNode;
            }
        }

        size++;

        afterAdd(newNode);
    }

    protected void afterAdd(Node<E> node) {
    
    
    }

    protected void afterRemove(Node<E> node) {
    
    
    }

    protected Node<E> createNewNode(E element, Node<E> parent) {
    
    
        return new Node<>(element, parent);
    }

    @Override
    public void remove(E element) {
    
    
        remove(findNode(element));
    }

    private void remove(Node<E> node) {
    
    
        if (null == node) return;

        if (node.hasTwoChildren()) {
    
    
            Node<E> s = successor(node);
            node.element = s.element;
            node = s;
        }

        Node<E> replacement = node.left == null ? node.right : node.left;
        if (replacement == null) {
    
     // 叶子节点
            if (node.parent == null) {
    
    
                root = null;
            } else if (node.parent.left == node) {
    
    
                node.parent.left = null;
            } else {
    
    
                node.parent.right = null;
            }
        } else {
    
     // 度为1的节点
            replacement.parent = node.parent;
            if (node.parent == null) {
    
    
                root = replacement;
            } else if (node.parent.left == node) {
    
    
                node.parent.left = replacement;
            } else {
    
    
                node.parent.right = replacement;
            }
        }

        size--;

        afterRemove(node);

    }

    private Node<E> findNode(E element) {
    
    
        if (null == element) return null; // 不支持添加null元素

        Node<E> node = root;
        int compare;
        while (node != null) {
    
    
            compare = compare(element, node.element);
            if (compare == 0) {
    
    
                return node;
            } else if (compare < 0) {
    
    
                node = node.left;
            } else {
    
    
                node = node.right;
            }
        }
        return null;
    }

    @Override
    public boolean contains(E e) {
    
    
        return findNode(e) != null;
    }

    protected int compare(E e1, E e2) {
    
    
        if (null != comparator) {
    
    
            return comparator.compare(e1, e2);
        }

        return ((Comparable) e1).compareTo(e2);
    }

}

AVLTree

package taught_by_mjlmj.tree;

import java.util.Comparator;

public class AVLTree<E> extends BinarySearchTree<E> {
    
    

    public AVLTree() {
    
    
    }

    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);
            }
        }
    }

    private void reBalance2(Node<E> grand) {
    
    
        AVLNode<E> g = (AVLNode<E>) grand;
        AVLNode<E> p = g.tallerSubAVLNode();
        AVLNode<E> n = p.tallerSubAVLNode();

        if (p.isLeftOfParent()) {
    
     // L
            if (n.isLeftOfParent()) {
    
     // LL
                rotate(g, n.left, n, n.right, p, p.right, g, g.right);
            } else {
    
     // LR
                rotate(g, p.left, p, n.left, n, n.right, g, g.right);
            }
        } else {
    
     // R
            if (n.isLeftOfParent()) {
    
     // RL
                rotate(g, g.left, g, n.left, n, n.right, p, p.right);
            } else {
    
     // RR
                rotate(g, g.left, g, p.left, p, n.left, n, n.right);
            }
        }
    }

    private void rotate(
            Node<E> r,
            Node<E> a, Node<E> b, Node<E> c,
            Node<E> d,
            Node<E> e, Node<E> f, Node<E> g
    ) {
    
    

        if (r.isLeftOfParent()) {
    
    
            r.parent.left = d;
        } else if (r.isRightOfParent()) {
    
    
            r.parent.right = d;
        } else {
    
    
            root = d;
        }
        d.parent = r.parent;

        b.left = a;
        if (a != null) a.parent = b;
        b.right = c;
        if (c != null) c.parent = b;
        updateHeight(b);

        f.left = e;
        if (e != null) e.parent = f;
        f.right = g;
        if (g != null) g.parent = f;
        updateHeight(f);

        d.left = b;
        d.right = f;
        b.parent = d;
        f.parent = d;
        updateHeight(d);

    }

    private void reBalance(Node<E> grand) {
    
    
        AVLNode<E> g = (AVLNode<E>) grand;
        AVLNode<E> p = g.tallerSubAVLNode();
        AVLNode<E> n = p.tallerSubAVLNode();

        if (p.isLeftOfParent()) {
    
     // L
            if (n.isLeftOfParent()) {
    
     // LL
                rotateRight(g);
            } else {
    
     // LR
                rotateLeft(p);
                rotateRight(g);
            }
        } else {
    
     // R
            if (n.isLeftOfParent()) {
    
     // RL
                rotateRight(p);
                rotateLeft(g);
            } else {
    
     // RR
                rotateLeft(g);
            }
        }

    }

    // 右旋转
    private void rotateRight(AVLNode<E> g) {
    
    
        AVLNode<E> p = (AVLNode<E>) g.left;

        if (p.right != null) p.right.parent = g;

        g.left = p.right;
        p.right = g;

        afterRotate(g, p);

    }

    // 左旋转
    private void rotateLeft(AVLNode<E> g) {
    
    
        AVLNode<E> p = (AVLNode<E>) g.right;

        if (p.left != null) p.left.parent = g;

        g.right = p.left;
        p.left = g;

        afterRotate(g, p);

    }

    private void afterRotate(AVLNode<E> g, AVLNode<E> p) {
    
    

        if (g.parent != null) {
    
    
            if (g.isLeftOfParent()) {
    
    
                g.parent.left = p;
            } else {
    
    
                g.parent.right = p;
            }
        } else {
    
    
            root = p;
        }
        p.parent = g.parent;

        g.parent = p;

        updateHeight(g);
        updateHeight(p);
    }

    @Override
    protected Node<E> createNewNode(E element, Node<E> parent) {
    
    
        return new AVLNode<>(element, parent);
    }

    private void updateHeight(Node<E> node) {
    
    
        ((AVLNode<E>) node).updateHeight();
    }

    private boolean isBalanced(Node<E> node) {
    
    
        return ((AVLNode<E>) node).isBalanced();
//        return Math.abs(((AVLNode<E>) node).balanceFactor()) <= 1;
    }

    private static class AVLNode<E> extends Node<E> {
    
    

        // 叶子节点的高度默认为1
        int height = 1;

        AVLNode(E element, Node<E> parent) {
    
    
            super(element, parent);
        }

        int leftSubTreeHeight() {
    
    
            int l = 0;
            if (left != null) l = ((AVLNode<E>) left).height;
            return l;
        }

        int rightSubTreeHeight() {
    
    
            int r = 0;
            if (right != null) r = ((AVLNode<E>) right).height;
            return r;
        }

        int balanceFactor() {
    
    
            return leftSubTreeHeight() - rightSubTreeHeight();
        }

        void updateHeight() {
    
    
            height = Math.max(leftSubTreeHeight(), rightSubTreeHeight()) + 1;
        }

        boolean isBalanced() {
    
    
            return Math.abs(balanceFactor()) <= 1;
        }

        // 返回左右子树较高的节点
        AVLNode<E> tallerSubAVLNode() {
    
    
            if (leftSubTreeHeight() > rightSubTreeHeight()) return (AVLNode<E>) left;
            else if (leftSubTreeHeight() < rightSubTreeHeight()) return (AVLNode<E>) right;
            else {
    
    
                if (isLeftOfParent()) return (AVLNode<E>) left;
                else return (AVLNode<E>) right;
            }
        }

        @Override
        public String toString() {
    
    
            String p = parent != null ? parent.element.toString() : "null";
            return p + "_" + element;
//            return height + "_" + element;
        }

        //        int balanceFactor() {
    
    
//            int l = 0;
//            int r = 0;
//            if (left != null) l = ((AVLNode<E>) left).height;
//            if (right != null) r = ((AVLNode<E>) right).height;
//            return l - r;
//        }
//
//        void updateHeight() {
    
    
//            int l = 0;
//            int r = 0;
//            if (left != null) l = ((AVLNode<E>) left).height;
//            if (right != null) r = ((AVLNode<E>) right).height;
//
//            height = Math.max(l, r) + 1;
//        }
//
//        boolean isBalanced() {
    
    
//            int l = 0;
//            int r = 0;
//            if (left != null) l = ((AVLNode<E>) left).height;
//            if (right != null) r = ((AVLNode<E>) right).height;
//
//            return Math.abs(l - r) <= 1;
//        }

    }

    @Override
    public Object string(Object node) {
    
    
        return node;
    }

}

总结

在这里插入图片描述

参考

小码哥李明杰老师课程: 恋上数据结构与算法 第一季.

小码哥李明杰老师博客: M了个J.


本文完,感谢您的关注支持!


猜你喜欢

转载自blog.csdn.net/weixin_44018671/article/details/120535745