爆肝封装二叉树、二叉搜索树、平衡二叉搜索树、AVL树、红黑树——树篇

本文主要回顾二叉树、二叉搜索树、平衡二叉搜索树、AVL树、B树、红黑树。包含具体的实现代码、部分方法的注释。
树间的继承关系:

  1. BinaryTree实现BinaryTreeInfo接口
  2. BinarySearchTree继承BinaryTree
  3. BalanceBinarySearchTree继承BinarySearchTree
  4. AVLTree和RBTree继承BalanceBinarySearchTree

二叉树

◼ 二叉树的特点
每个节点的度最大为 2(最多拥有 2 棵子树)
左子树和右子树是有顺序的
即使某节点只有一棵子树,也要区分左右子树

代码
BinaryTreeInfo.java //BianryTree实现的接口

package com.mj.printer;

public interface BinaryTreeInfo {
    
    
	/**
	 * who is the root node
	 */
	Object root();
	/**
	 * how to get the left child of the node
	 */
	Object left(Object node);
	/**
	 * how to get the right child of the node
	 */
	Object right(Object node);
	/**
	 * how to print the node
	 */
	Object string(Object node);
}

package _08_红黑树.tree;

import java.util.LinkedList;
import java.util.Queue;

import com.mj.printer.BinaryTreeInfo;
@SuppressWarnings("all")
public class BinaryTree2<E> implements BinaryTreeInfo {
    
    
    protected int size;
    protected Node<E> root;

    public int size(){
    
    
        return size;
    }

    public boolean isEmpty(){
    
    
        return size == 0;
    }

    public void clear(){
    
    
        root = null;
        size = 0;
    }

    public void preorder(Visitor<E> visitor){
    
    
        if (visitor == null) return ;
        preorder(root, visitor);
    }

    public void preorder(Node<E> node, Visitor<E> visitor){
    
    
        if (node == null || visitor.stop) return;
        visitor.stop = visitor.visit(node.element);
        preorder(node.left, visitor);
        preorder(node.right, visitor);
    }

    public void inorder(Visitor<E> visitor){
    
    
        if (visitor == null) return;
        inorder(root, visitor);
    }

    public void inorder(Node<E> node, Visitor visitor){
    
    
        if (node == null || visitor.stop) return;
        inorder(node.left, visitor);

        if (visitor.stop) return;
        visitor.stop = visitor.visit(node.element);

        inorder(node.right, visitor);

    }

    public void postorder(Visitor<E> visitor){
    
    
        if (visitor == null) return;
        postorder(root, visitor);
    }

    public void postorder(Node<E> node, Visitor<E> visitor){
    
    
        if (node == null || visitor.stop) return;

        postorder(node.left, visitor);
        postorder(node.right, visitor);
        if (visitor.stop) return;
        visitor.stop = visitor.visit(node.element);

    }

    public void levelOrder(Visitor<E> visitor){
    
    
        if (root == null || visitor.stop) return;

        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
    
    
            Node<E> node = queue.poll();

            if (visitor.stop)return;
            visitor.stop = visitor.visit(node.element);

            if (node.left != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
    }

    /**
     * 判断该树是否是一颗完全二叉树
     * @return
     */
    public boolean isComplete(){
    
    
        if (root == null) return true;

        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(root);

        boolean leaf = false;
        while( !queue.isEmpty()){
    
    
            Node<E> node = queue.poll();
            if (leaf && !node.isLeaf()) return false;

            if (node.left != null){
    
    
                queue.offer(node.left);
            } else if (node.right != null){
    
    
                return false;
            }

            if (node.right != null){
    
    
                queue.offer(node.right);
            } else{
    
         //后面遍历的节点必须是叶子节点
                leaf = true;
            }

        }
        return true;
    }

    public int height(){
    
    
        if (root == null) return 0;

        //树的高度
        int height = 0;
        //存储着每一层元素的数量
        int levelSize = 1;
        Queue<Node<E>> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
    
    
            levelSize--;
            Node<E> node = queue.poll();

            if (node.left != null){
    
    
                queue.offer(node.left);
            }
            if (node.right != null){
    
    
                queue.offer(node.right);
            }

            if (levelSize == 0){
    
        //意味着即将要访问下一层
                height++;
                levelSize = queue.size();
            }

        }
        return height;
    }

    public int height2(){
    
    
        return height(root);
    }

    public int height(Node<E> node){
    
    
        if (node == null) return 0;

        return Math.max(height(node.left), height(node.right)) + 1;
    }
    /*
    *
    * 创建一个节点
     */
    protected Node<E> createNode(E element, Node<E> parent){
    
    
        return new Node<E>(element, parent);
    }

    protected Node<E> predecessor(Node<E> node){
    
    
        if (node == null) return null;

        //前驱节点在左子树中
        Node<E> p = node.left;
        if (p != null){
    
    
            while (p.right != null){
    
    
                p = p.right;
            }
            return p;
        }
        //从父节点 祖父节点中寻找前驱
        while (node.parent != null && node.parent.left == node){
    
    
            node = node.parent;
        }
        //node.parent == null
        // node.parent.right == node

        return node.parent;
    }


    protected Node<E> successor(Node<E> node){
    
    
        if (node == null) return null;

        //后继节点在右子树中
        Node<E> p = node.right;
        if (p != null){
    
    
            while (p != null){
    
    
                p = p.left;
            }
            return p;
        }
        //从父节点中找
        while (node.parent != null && node == node.parent.right){
    
    
            node = node.parent;
        }

        return node.parent;
    }

    protected static class Node<E>{
    
    
        E element;
        Node<E> left;
        Node<E> right;
        Node<E> parent;
        public Node(E element, Node<E> parent){
    
    
            this.element = element;
            this.parent = parent;
        }

        public boolean isLeaf(){
    
    
            return left == null && right == null;
        }

        public boolean hasTwoChildren(){
    
    
            return left != null && right != null;
        }

        public boolean isLeftChild(){
    
    
            return parent != null && this == parent.left;
        }

        public boolean isRightChild(){
    
    
            return parent != null && this == parent.right;
        }

        public Node<E> sibling(){
    
    
            if (isLeftChild()){
    
    
                return parent.right;
            }
            if (isRightChild()){
    
    
                return parent.left;
            }
            return null;
        }

    }


    @Override
    public Object root() {
    
    
        return root;
    }

    @Override
    public Object left(Object node) {
    
    
        return ((Node<E>)node).left;
    }

    @Override
    public Object right(Object node) {
    
    
        return ((Node<E>)node).right;
    }

    @Override
    public Object string(Object node) {
    
    
        return node;
    }
    public static abstract class Visitor<E>{
    
    
        boolean stop;

        /**
         *
         * @param element
         * @return 如果返回true,就代表遍历停止。
         */

        abstract boolean visit(E element);
    }

}

二叉搜索树

◼ 二叉搜索树是二叉树的一种,是应用非常广泛的一种二叉树,英文简称为 BST
又被称为:二叉查找树、二叉排序树
任意一个节点的值都大于其左子树所有节点的值
任意一个节点的值都小于其右子树所有节点的值
它的左右子树也是一棵二叉搜索树

代码

package _08_红黑树.tree;

import java.util.Comparator;
@SuppressWarnings("unchecked")
public class BST2<E> extends BinaryTree2<E> {
    
    
    private Comparator<E> comparator;

    public BST2(){
    
    
        this(null);
    }

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

    public void add(E element){
    
    
        elementNotNullCheck(element);

        //添加第一个节点
        if (root == null){
    
    
            root = createNode(element, null);
            size++;

            //新添加节点之后的处理
            afterAdd(root);
            return;
        }

        //添加的不是第一个节点 找到父节点
        Node<E> parent = root;
        Node<E> node = root;
        int cmp = 0;
        do {
    
    
            cmp = compare(element, node.element);
            parent = node;
            if(cmp > 0){
    
    
                node = node.right;
            } else if (cmp < 0){
    
    
                node = node.left;
            }else{
    
    
                node.element = element;
                return;
            }

        }while (node != null);

        //看看插入到父节点哪个位置
        Node<E> newNode = createNode(element, parent);
        if (cmp > 0){
    
    
            parent.right = newNode;
        }else{
    
    
            parent.left = newNode;
        }
        size++;

        //新添加结点之后的处理
        afterAdd(newNode);

    }

    /**
     * 添加节点之后的处理
     * @param node
     */
    protected void afterAdd(Node<E> node){
    
    

    }

    protected void afterRemove(Node<E> node){
    
    

    }

    public void remove(E element){
    
    
        remove(node(element));
    }

    public boolean contains(E element){
    
    
        return node(element) != null;
    }

    public void remove(Node<E> node){
    
    
        if ( node == null) return;
        size--;

        if (node.hasTwoChildren()){
    
     //度为2的节点
            //找到后继节点
            Node<E> s = successor(node);
            //用后继节点的值覆盖当前节点
            node.element = s.element;
            //删除后继节点
            node = s;
        }

        //删除node节点 node必定为度为1或0的节点
        Node<E> replacement = node.left != null ? node.left : node.right;

        if (replacement != null){
    
      //node是度为1的结点
            //更改parent
            replacement.parent = node.parent;
            //更改parent的left right指向
            if (node.parent == null){
    
     //node是度为1的节点并且是根节点
                root = replacement;
            } else if (node.parent.left == node){
    
    //node在父节点左边
                node.parent.left = replacement;
            }else{
    
    
                node.parent.right = replacement;
            }

            //删除节点之后的处理
            afterRemove(replacement);

        }else if (node.parent == null){
    
     //node是度为0的节点(叶子节点)并且是根节点
            root = null;

            afterRemove(node);
        } else{
    
     //node是叶子节点, 但不是根节点
            if (node == node.parent.left){
    
    
                node.parent.left = null;
            }else{
    
    
                node.parent.right = null;
            }
            //删除节点之后的处理
            afterRemove(node);
        }
    }
    /**
     * 按值查找节点
     * @param element
     * @return 目标节点
     */
    private Node<E> node(E element){
    
    
        Node<E> node = root;
        while (node != null){
    
    
            int cmp = compare(element,node.element);
            if (cmp == 0) return node;
            if (cmp > 0){
    
    
                node = node.right;
            }else{
    
    
                node = node.left;
            }
        }
        return null;
    }

    /**
     * 二叉搜索树的每个节点必须具有可比较性
     * @param e1
     * @param e2
     * @return
     */
    private int compare(E e1, E e2){
    
    
        if (comparator != null){
    
    
            return comparator.compare(e1, e2);
        }

        //没有比较器就必须实现Comparable<E>接口 否则下面这句就报错
        return ((Comparable<E>)e1).compareTo(e2);
    }

    private void elementNotNullCheck(E element){
    
    
        if (element == null ){
    
    
            throw new IllegalArgumentException("element must not be null!");
        }
    }

}

平衡二叉搜索树

◼ 英文简称为:BBST
◼ 经典常见的平衡二叉搜索树有
AVL树
✓ Windows NT 内核中广泛使用
红黑树
✓ C++ STL(比如 map、set )
✓ Java 的 TreeMap、TreeSet、HashMap、HashSet
✓ Linux 的进程调度
✓ Ngix 的 timer 管理
一般也称它们为:自平衡的二叉搜索树(Self-balancing Binary Search Tree)

package _08_红黑树.tree;

import java.util.Comparator;
public class BBST2<E> extends BST2<E> {
    
    
    public BBST2(){
    
    
        this(null);//调用他自己的构造方法
    }

    public BBST2(Comparator<E> comparator){
    
    
        super(comparator);  //将comparator传入父类的构造方法中
    }

    /**
     * 左旋
     * @param grand
     */
    protected void rotateLeft(Node<E> grand){
    
    
        Node<E> parent = grand.right;
        Node<E> child = parent.left;
        grand.right = child;
        parent.left = grand;    //让parent称为根节点
        afterRotate(grand, parent, child);
    }

    /**
     * 右旋
     * @param grand
     */
    protected void rotateRight(Node<E> grand){
    
    
        Node<E> parent = grand.left;
        Node<E> child = parent.right;
        grand.left = child;
        parent.right = grand;      //让parent成为根节点
        afterRotate(grand, parent, child);
    }

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

    /**
     * 统一旋转操作
     *
     */
    protected 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;
        }

        //e-f
        f.left = e;
        if (e != null){
    
    
            e.parent = f;
        }

        //b-d-f
        d.left = b;
        d.right = f;
        b.parent = d;
        f.parent = d;
    }

}

AVL树


◼ 平衡因子(Balance Factor):某结点的左右子树的高度差
◼ AVL树的特点
每个节点的平衡因子只可能是 1、0、-1(绝对值 ≤ 1,如果超过 1,称之为“失衡”)
每个节点的左右子树高度差不超过 1
搜索、添加、删除的时间复杂度是 O(logn)

代码

package _08_红黑树.tree;

import java.util.Comparator;
@SuppressWarnings("all")
public class AVLTree2<E> extends BBST2<E> {
    
    
    public AVLTree2(){
    
    
        this(null);
    }

    public AVLTree2(Comparator<E> comparator){
    
    
        super(comparator);

    }

    //添加元素 一定是加到叶子结点上, 可能会导致所有祖先节点都失衡 所以一直循环往上找
    protected void afterAdd(Node<E> node){
    
    
        while((node = node.parent ) != null){
    
    
            if (isBalanced(node)){
    
    
                //更新高度
                updateHeight(node);
            }else{
    
    
                //恢复平衡
                rebalance(node);
                //整棵树恢复平衡
                break;
            }
        }

    }

    /**
     * 删除 : 可能会导致父节点或祖先节点失衡(只有1个节点会失衡),其他节点,都不可能失衡
     *      * 更高层的祖先节点可能也会失衡,需要再次恢复平衡,然后又可能导致更高层的祖先节点失衡...
     *      * 极端情况下,所有祖先节点都需要进行恢复平衡的操作,共 O(logn) 次调整
     * @param node 被删除的节点 或者 用以取代被删除节点的子节点(当被删除节点的度为1)
     */
    protected void afterRemove(Node<E> node){
    
    
        while ((node = node.parent) != null){
    
    
            if (isBalanced(node)){
    
    
                //更新高度
                updateHeight(node);
            } else{
    
    
                //恢复平衡
                rebalance(node);
            }
        }
    }

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

    /**
     * 恢复平衡
     * @param grand  高度最低的那个不平衡点
     */
    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);
            }

        }
    }

    @Override
    protected void afterRotate(Node<E> grand, Node<E> parent, Node<E> child) {
    
    
        super.afterRotate(grand, parent, child);

        // 更新高度
        updateHeight(grand);
        updateHeight(parent);
    }

    /**
     * 统一旋转 调用父类的rotate函数
     * @param r  根节点
     * @param b
     * @param c
     * @param d
     * @param e
     * @param f
     */
    @Override
    protected void rotate(Node<E> r, Node<E> b, Node<E> c, Node<E> d, Node<E> e, Node<E> f) {
    
    
        super.rotate(r, b, c, d, e, f);

        // 更新高度
        updateHeight(b);
        updateHeight(f);
        updateHeight(d);
    }

    /**
     * 恢复平衡 添加和删除节点都有可能导致失去平衡
     * 添加 : 最坏情况:可能会导致所有祖先节点都失衡
     * 删除 : 可能会导致父节点或祖先节点失衡(只有1个节点会失衡),其他节点,都不可能失衡
     * 更高层的祖先节点可能也会失衡,需要再次恢复平衡,然后又可能导致更高层的祖先节点失衡...
     * 极端情况下,所有祖先节点都需要进行恢复平衡的操作,共 O(logn) 次调整
     * @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);
            }
        }
    }

    /**
     * 看这个结点是否平衡 即看这个节点的平衡因子绝对值是否小于等于1
     * @param node
     * @return
     */
    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;    //左右两边相等的情况
        }

        public String toString() {
    
    
            String parentString = "null";
            if (parent != null){
    
    
                parentString = parent.element.toString();
            }
            return element + "_p(" + parentString + ")_h(" + height + ")";
        }

    }

}

红黑树

◼ 红黑树也是一种自平衡的二叉搜索树
以前也叫做平衡二叉B树(Symmetric Binary B-tree)
◼ 红黑树必须满足以下 5 条性质

  1. 节点是 RED 或者 BLACK
  2. 根节点是 BLACK
  3. 叶子节点(外部节点,空节点)都是 BLACK
  4. RED 节点的子节点都是 BLACK
    ✓ RED 节点的 parent 都是 BLACK
    ✓ 从根节点到叶子节点的所有路径上不能有 2 个连续的 RED 节点
  5. 从任一节点到叶子节点的所有路径都包含相同数目的 BLACK 节点

代码

package _08_红黑树.tree;

import java.util.Comparator;

public class RBTree2<E> extends BBST2<E> {
    
    
    private static final boolean RED = false;
    private static final boolean BLACK = true;

    public RBTree2() {
    
    
        this(null);
    }

    public RBTree2(Comparator<E> comparator) {
    
    
        super(comparator);
    }

    /**
     * 红黑数等姐于4阶B树 添加时只能在叶子节点上加,共12种情况 可能会导致树失衡
     * 对12种情况进行处理
     * @param node
     */
    protected void afterAdd(Node<E> node) {
    
    
        Node<E> parent = node.parent;

        // 添加的是根节点 或者
        // 上溢到达了根节点(根节点中间的值自己上去成为新的根节点 没有parent)
        if (parent == null) {
    
    
            black(node);
            return;
        }

        // 如果父节点是黑色,直接返回
        if (isBlack(parent)) return;

        // 叔父节点
        Node<E> uncle = parent.sibling();
        // 祖父节点 //添加时不合规的那八种情况,修复的时候grand都是要染成红色的
        Node<E> grand = red(parent.parent);
        if (isRed(uncle)) {
    
     // 叔父节点是红色【B树节点上溢】
            black(parent);
            black(uncle);
            // 把祖父节点当做是新添加的节点 向上合并
            afterAdd(grand);
            return;
        }

        // 叔父节点不是红色
        if (parent.isLeftChild()) {
    
     // L
            if (node.isLeftChild()) {
    
     // LL
                black(parent);
            } else {
    
     // LR
                black(node);
                rotateLeft(parent);
            }
            rotateRight(grand);
        } else {
    
     // R
            if (node.isLeftChild()) {
    
     // RL
                black(node);
                rotateRight(parent);
            } else {
    
     // RR
                black(parent);
            }
            rotateLeft(grand);
        }
    }

    /**
     *  B树中,最后真正被删除的元素都在叶子节点中
     *  删除红色节点不需要处理
     *  删除黑色节点
     *  ◼ 有 3 种情况 可能会导致红黑树失衡
     * 拥有 2 个 RED 子节点的 BLACK 节点
     * ✓ 不可能被直接删除,因为会找它的子节点替代删除
     * ✓ 因此不用考虑这种情况
     * 拥有 1 个 RED 子节点的 BLACK 节点
     * BLACK 叶子节点
     * @param node
     */
    @Override
    protected void afterRemove(Node<E> node) {
    
    
        // 如果删除的节点是红色
        // 或者 用以取代删除节点的子节点是红色
        if (isRed(node)) {
    
    
            black(node);
            return;
        }

        Node<E> parent = node.parent;
        // 删除的是根节点
        if (parent == null) return;

        // 删除的是黑色叶子节点【下溢】
        // 判断被删除的node是左还是右
        boolean left = parent.left == null || node.isLeftChild();
        Node<E> sibling = left ? parent.right : parent.left;
        if (left) {
    
     // 被删除的节点在左边,兄弟节点在右边
            if (isRed(sibling)) {
    
     // 兄弟节点是红色
                black(sibling);
                red(parent);
                rotateLeft(parent);
                // 更换兄弟
                sibling = parent.right;
            }

            // 兄弟节点必然是黑色
            if (isBlack(sibling.left) && isBlack(sibling.right)) {
    
    
                // 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
                boolean parentBlack = isBlack(parent);
                black(parent);
                red(sibling);
                if (parentBlack) {
    
    
                    afterRemove(parent);
                }
            } else {
    
     // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
                // 兄弟节点的左边是黑色,兄弟要先旋转
                if (isBlack(sibling.right)) {
    
    
                    rotateRight(sibling);
                    sibling = parent.right;
                }

                color(sibling, colorOf(parent));
                black(sibling.right);
                black(parent);
                rotateLeft(parent);
            }
        } else {
    
     // 被删除的节点在右边,兄弟节点在左边
            if (isRed(sibling)) {
    
     // 兄弟节点是红色
                black(sibling);
                red(parent);
                rotateRight(parent);
                // 更换兄弟
                sibling = parent.left;
            }

            // 兄弟节点必然是黑色
            if (isBlack(sibling.left) && isBlack(sibling.right)) {
    
    
                // 兄弟节点没有1个红色子节点,父节点要向下跟兄弟节点合并
                boolean parentBlack = isBlack(parent);
                black(parent);
                red(sibling);
                if (parentBlack) {
    
    
                    afterRemove(parent);
                }
            } else {
    
     // 兄弟节点至少有1个红色子节点,向兄弟节点借元素
                // 兄弟节点的左边是黑色,兄弟要先旋转
                if (isBlack(sibling.left)) {
    
    
                    rotateLeft(sibling);
                    sibling = parent.left;
                }

                color(sibling, colorOf(parent));
                black(sibling.left);
                black(parent);
                rotateRight(parent);
            }
        }
    }



    private Node<E> color(Node<E> node, boolean color) {
    
    
        if (node == null) return node;
        ((RBNode2<E>)node).color = color;
        return node;
    }

    private Node<E> red(Node<E> node) {
    
    
        return color(node, RED);
    }

    private Node<E> black(Node<E> node) {
    
    
        return color(node, BLACK);
    }

    private boolean colorOf(Node<E> node) {
    
    
        return node == null ? BLACK : ((RBNode2<E>)node).color;
    }

    private boolean isBlack(Node<E> node) {
    
    
        return colorOf(node) == BLACK;
    }

    private boolean isRed(Node<E> node) {
    
    
        return colorOf(node) == RED;
    }

    @Override	//重写父类的创建结点方法
    protected Node<E> createNode(E element, Node<E> parent) {
    
    
        return new RBNode2<E>(element, parent);
    }

    private static class RBNode2<E> extends Node<E> {
    
    
        boolean color = RED;
        public RBNode2(E element, Node<E> parent) {
    
    
            super(element, parent);
        }

        @Override
        public String toString() {
    
    
            String str = "";
            if (color == RED) {
    
    
                str = "R_";
            }
            return str + element.toString();
        }
    }

}

有问题欢迎评论、私信。

如果觉得本文对你的学习有帮助,还请一键三连!

猜你喜欢

转载自blog.csdn.net/Mrrr_Li/article/details/111318726