红黑树

红黑树(RBT)定义

1.是一个二叉搜索树

2.每个节点要么是红的,要么是

3.根节点是黑色的,并定义null 为 黑色

4.如果一个子结点是红色的,那么它的两个儿子都是黑色,且父节点也是黑色

5.对于任意一个结点而言,它到叶节点的每一条路径都包含相同数目的的黑色结点,称之为黑高

6.任意一棵以黑色节点为根的子树也必定是一颗红黑树

7.左右子树的高度最多是左右子树的两倍,则:若H(left)>H(right)  则 H(left)<=2*H(right)+1

 

 

o交换所有节点的左右子树

1

2中序

3后序

4层序

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

public class InvertBinaryTree {
    //交换所有节点的左右子树
    //               4                   4
//                2      7            7       2
    //          1  3   6  9         9   6   3   1

//先序遍历
    public TreeNode invertTreeByPre(TreeNode root){
        if (root!=null){
            TreeNode temp= root.left;
            root.left=root.right;
            root.right=temp;
            invertTreeByPre(root.left);
            invertTreeByPre(root.right);
            return root;
        }else {
            return null;
        }
    }

//  后序遍历
public TreeNode invertTreeByPost(TreeNode root){
    if (root!=null){
        invertTreeByPre(root.left);
        invertTreeByPre(root.right);
        TreeNode temp= root.left;
        root.left=root.right;
        root.right=temp;

        return root;
    }else {
        return null;
    }
}


    //  中序遍历
    public TreeNode invertTreeByMid(TreeNode root){
        if (root!=null){
            invertTreeByPre(root.left);
            TreeNode temp= root.left;
            root.left=root.right;
            root.right=temp;
            invertTreeByPre(root.left); //由于此时左右子树已经完成交换,所以递归右子树真正意义上是递归左子树

            return root;
        }else {
            return null;
        }
    }

    //层序遍历
    public TreeNode invertTreeByLever(TreeNode root){
        if (root==null) {return null;}
        else {
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()){
                TreeNode p = queue.poll();
                TreeNode temp= p.left;
                p.left=p.right;
                p.right = temp;
                if (p.left!=null) {
                    queue.offer(p.left);
                }
                if (p.right!=null) {
                    queue.offer(p.right);
                }
            }
        }
        return root;
    }

}

二叉排序树、二叉搜索树BST到AVL树

具有如下性质:

n定义空树是一个BST

n树所有结点的值均小于根结点的

n右子树所有结点的值均大于根结点的

n左右子树都是BST(递归定义)

n序遍历序列为升序

 

迭代器 利用中序遍历

import java.util.ArrayList;
import java.util.Iterator;

public class BSTIterator {
    private Iterator<Integer> itr;

    public BSTIterator(TreeNode root){
        ArrayList<Integer>  list = new ArrayList<>();
        inOrder(root,list);
        itr = list.iterator();
    }
    //递归
    private  void inOrder(TreeNode p,ArrayList<Integer> list){
        if (p!=null){
            inOrder(p.left, list);
            list.add(p.val);
            inOrder(p.right, list);
        }
    }
    public boolean hasNext(){
        return itr.hasNext();
    }

    public int  next(){
        return itr.next();
    }

}

 节点

import java.util.Map;

public class AVLEntry<K,V> implements Map.Entry<K,V> {
    public K key;
    public V value;
    public AVLEntry<K,V> left;
    public AVLEntry<K,V> right;
    public int height=1;
    @Override
    public K getKey() {
        return key;
    }
    @Override
    public V getValue() {
        return value;
    }
    @Override
    public V setValue(V value) {
        this.value = value;
        return value;
    }
    public AVLEntry() {
    }
    public AVLEntry(K key, V value) {
        this.key = key;
        this.value = value;
    }
    public AVLEntry(K key) {
        this.key = key;
    }
    @Override
    public String toString() {
        return "AVLEntry{" +
                "key=" + key +
                ", value=" + value +
                ", height=" + height +
                '}';
    }
    public AVLEntry(K key, V value, AVLEntry<K, V> left, AVLEntry<K, V> right) {
        this.key = key;
        this.value = value;
        this.left = left;
        this.right = right;
    }
}

 字典

import org.junit.Assert;

import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class AVLMap<K, V> implements Iterable<AVLEntry<K, V>> {
    private int size;
    private AVLEntry<K, V> root;
    private Comparator<K> comparator;   //比较器
    private LinkedList<AVLEntry<K,V>> stack = new LinkedList<>();  //辅助栈 实现 插入调整的非递归算法

    @SuppressWarnings("unchecked")
    private int compare(K a, K b) {  //比较关键字的大小
        if (comparator != null) {
            return comparator.compare(a, b);
        } else {
            Comparable<K> c = (Comparable<K>) a;
            return c.compareTo(b);
        }
    }

    public AVLMap() {
    }

    public AVLMap(Comparator<K> comparator) {
        this.comparator = comparator;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0 ? true : false;
    }

    public V put(K key, V value) {
        if (root == null) {
            root = new AVLEntry<>(key, value);
            stack.push(root);  // 要把插入时的所有路径全部压栈
            size++;
        } else {
            AVLEntry<K, V> p = root;
            while (p != null) {
                stack.push(p);
                int compareResult = compare(key, p.key);
                if (compareResult == 0) {
                    p.setValue(value);
                    break;
                } else if (compareResult < 0) {
                    if (p.left == null) {
                        p.left = new AVLEntry<>(key, value);
                        size++;
                        stack.push(p.left);
                        break;
                    } else {
                        p = p.left;
                    }
                } else { //1
                    if (p.right == null) {
                        p.right = new AVLEntry<>(key, value);
                        size++;
                        stack.push(p.right);
                        break;
                    } else {//2
                        p = p.right;
                    }//2
                }//1

            }//while

        }//else
        fixAfterInsertion(key);
        return value;
    }

    private void fixAfterInsertion(K key){
        AVLEntry<K,V> p =root;  //定义一个指针p
        while (!stack.isEmpty()){  //弹栈  不断弹栈的过程就是指针回溯的过程
            p=stack.pop();
            int newHeight = Math.max(getHeight(p.left),getHeight(p.right))+1;  //重新计算节点p的高度
            if (p.height>1&&newHeight==p.height){    //  高度并未发生改变
                stack.clear();
                return;
            }
            p.height = newHeight;
            int d= getHeight(p.left) - getHeight(p.right);  //平衡因子
            if (Math.abs(d)<=1){
                continue;
            }else {
                if (d==2){ //说明是左子树
                    if(compare(key,p.left.key)<0){
                        //情况一(左子树的左子树)
                        p=rotateRight(p);
                    }else {
                        //情况二(左子树的右子树)
                        p=firstLeftThenRight(p);
                    }
                }else {  // 否则说明是右子树
                    if (compare(key,p.right.key)>0){
                        //情况三(右子树的右子树)
                        p=rotateLeft(p);
                    }else {
                        //情况四(右子树的左子树)
                        p=firstRightThenLeft(p);
                    }
                }
                //确定爷爷节点
                if (!stack.isEmpty()){
                    if (compare(key,stack.peek().key)<0){  //关键字小于栈顶元素
                        //表明插入到了左子树
                        stack.peek().left = p;
                    }else {
                        //插入到了右子树
                        stack.peek().right= p;
                    }
                }

            }
        }
        root =p;
    }

    //用于检测整个树是否是平衡的
    public void checkBalance(){
        postOrderCheckBalance(root);
    }

    private void postOrderCheckBalance(AVLEntry<K,V> p){
        if (p!=null){
            postOrderCheckBalance(p.left);
            postOrderCheckBalance(p.right);
            Assert.assertTrue(Math.abs(getHeight(p.left)-getHeight(p.right))<=1);

        }
    }



    public int getHeight(AVLEntry<K,V>  p) {
        return  p == null?0:p.height;
    }


    /*
     插入key到左子树引起平衡改变,及平衡因子为正数
     插入key到右子树引起平衡改变,及平衡因子为负数
     */

    //情况一  保证封装 将public 改为 private     key<left.key
    private AVLEntry<K,V>  rotateRight(AVLEntry<K,V> p){
        //首先取得p的左子树 L,(右子树为R),L的左子树为L-left 右子树L-right,右旋L的左子树不动,
        //  L代替P成为P.parent的子节点,L成为P的父节点,P的左子树为L-right,右子树为R
        AVLEntry<K,V> left =p.left;  //(注释中的L,要和p做交换)  找到L
        p.left=left.right ; // 将left的右子树 指向节点p的左子树  P的左子树为L-right
        left.right = p;    //p作为left的右子树   右旋左子树不动,p节点变为L的右子树


        p.height=Math.max(getHeight(p.left),getHeight(p.right))+1;
        left.height=Math.max(getHeight(left.left),p.height)+1;
        return left;
    }

    //情况三
    private AVLEntry<K,V> rotateLeft(AVLEntry<K,V> p){
        //首先取得 p的右子树,左旋右子树保持不变,p 左右孩子是L R   R的左右孩子是R-left R-right
        //  左旋保持右子树不变,即R-right不动,R变为p的父节点,p为R的左子树,p的左子树不变,右子树为R-left
        AVLEntry<K,V> right = p.right;   //  取得R节点
        p.right = right.left;           //   p的右孩子为R的左子树
        right.left=p;                  //    p变为R的左子树
        p.height=Math.max(getHeight(p.left),getHeight(p.right))+1;
        right.height = Math.max(p.height,getHeight(right.right))+1;
        return right;
    }

    //先左旋后右旋    情况二
    private AVLEntry<K,V>  firstLeftThenRight(AVLEntry<K,V> p){
        p.left = rotateLeft(p.left);
        p=rotateRight(p);
        return p;
    }


    //先右旋后左旋   情况四
    private AVLEntry<K,V>  firstRightThenLeft(AVLEntry<K,V> p){
        p.right = rotateRight(p.right);
        p=rotateLeft(p);
        return p;
    }

    private AVLEntry<K, V> getEntey(K key) {
        AVLEntry<K, V> p = root;
        while (p != null) {
            int compareResult = compare(key, p.key);
            if (compareResult == 0) {
                return p;
            } else if (compareResult < 0) {
                p = p.left;
            } else {
                p = p.right;
            }
        } //while
        return null;
    }

    public boolean containsKey(K key) {
        AVLEntry<K, V> p = getEntey(key);
        return p != null;
    }

    public V get(K key) {
        AVLEntry<K, V> p = getEntey(key);
        return p != null ? p.getValue() : null;
    }

    public boolean containsValue(V value) {
        Iterator<AVLEntry<K, V>> itr = this.iterator();
        while (itr.hasNext()) {
            if (itr.next().getValue().equals(value)) {
                return true;
            }
        }
        return false;
    }

    public AVLEntry<K, V> getFirstEntry(AVLEntry<K, V> p) {
        if (p == null) {
            return null;
        }
        while (p.left != null) {
            p = p.left;
        }
        return p;
    }

    public AVLEntry<K, V> getLastEntry(AVLEntry<K, V> p) {
        if (p == null) {
            return null;
        }
        while (p.right != null) {
            p = p.right;
        }
        return p;
    }

    public AVLEntry<K, V> deleteEntry(AVLEntry<K, V> p, K key) {
        if (p == null) {
            return null;
        } else {//0
            int cmopareResult = compare(key, p.key);
            if (cmopareResult == 0) {  //没有孩子为叶子节点,直接删除
                if (p.left == null && p.right == null) {
                    p = null;
                } else if (p.left != null && p.right == null) {
                    p = p.left;  //有一个孩子 将孩子赋值给父亲,即可
                } else if (p.right != null && p.left == null) {
                    p = p.right;
                } else {   //1 有两个孩子,找到右子树的最小值 ,
                    if ((size & 1) == 0) {
                        AVLEntry<K, V> rightMin = getFirstEntry(p.right);
                        p.key = rightMin.key;
                        p.value = rightMin.value;  //右子树中删除 key
                        AVLEntry<K, V> newRight = deleteEntry(p.right, p.key);
                        p.right = newRight;
                    } else {//2
                        if ((size & 1) == 0) {  //左子树的最大值
                            AVLEntry<K, V> leftMax = getLastEntry(p.left);
                            p.key = leftMax.key;
                            p.value = leftMax.value;  //左子树中删除key
                            AVLEntry<K, V> newLeft = deleteEntry(p.left, p.key);
                            p.left = newLeft;
                        }
                    }//2
                }//1
            } else if (cmopareResult < 0) {
                AVLEntry<K, V> newLeft = deleteEntry(p.left, key);
                p.left = newLeft;
            } else {
                AVLEntry<K, V> newRight = deleteEntry(p.right, key);
                p.left = newRight;
            }
            fixAfterDeletion(p);
            return p;
        }//0

    }

    public AVLEntry<K,V> fixAfterDeletion(AVLEntry<K,V> p){
        if (p==null){ // 边界检查
            return null;
        }else {
            p.height = Math.max(getHeight(p.left),getHeight(p.right))+1;  //计算节点P的高度
            int d = getHeight(p.left) - getHeight(p.right);              //计算平衡因子
            if (d == 2){
                if (getHeight(p.left.left)-getHeight(p.left.right)>=0){  //左子树高度大于右子树,满足情况一二
                    p =rotateRight(p);
                }else {
                    p = firstLeftThenRight(p);
                }
            }else if (d==-2){
                if (getHeight(p.right.right)-getHeight(p.right.left)>=0){
                    p =rotateLeft(p);
                }else{
                    p = firstRightThenLeft(p);
                }
            }
            return p;
        }
    }


    public V remove(K key) {
        AVLEntry<K, V> entry = getEntey(key);
        if (entry == null) {
            return null;
        }
        V oldValue = entry.getValue();
        root = deleteEntry(root, key);
        size--;
        return oldValue;
    }

    public void levelOrder() {
        Queue<AVLEntry<K, V>> queue = new LinkedList<>();
        queue.offer(root);
        int preCount = 1;
        int pCount = 0;
        while (!queue.isEmpty()) {
            preCount--;
            AVLEntry<K, V> p = queue.poll();
            System.out.println(p + " ");
            if (p.left != null) {
                queue.offer(p.left);
                pCount++;
            }
            if (p.right != null) {
                queue.offer(p.right);
                pCount++;
            }
            if (preCount == 0) {
                preCount = pCount;
                pCount = 0;
                System.out.println();
            }
        }
    }


    @Override
    public Iterator<AVLEntry<K, V>> iterator() {
        return new AVLIterator<K, V>(root);
    }
}

将排序数组转换为二叉树 

import java.util.HashMap;
import java.util.LinkedList;


class LeetCodeAVL {

    private int size;
    public TreeNode root;
    private LinkedList<TreeNode> stack = new LinkedList<TreeNode>();

    public int size() {
        return size;
    }
    public boolean isEmpty() {
        return size == 0 ? true : false;
    }

    public void put(int key) {
        if (root == null) {
            root = new TreeNode(key);
            stack.push(root);
            size++;
        } else {
            TreeNode p = root;
            while (p != null) {
                stack.push(p);
                int compareResult = key - p.val;
                if (compareResult == 0) {
                    break;
                } else if (compareResult < 0) {
                    if (p.left == null) {
                        p.left = new TreeNode(key);
                        size++;
                        stack.push(p.left);
                        break;
                    } else {
                        p = p.left;
                    }
                } else {
                    if (p.right == null) {
                        p.right = new TreeNode(key);
                        size++;
                        stack.push(p.right);
                        break;
                    } else {
                        p = p.right;
                    }
                }
            }
        }
        fixAfterInsertion(key);
    }
    private HashMap<TreeNode, Integer> heightMap = new HashMap<TreeNode, Integer>();
    public int getHeight(TreeNode p) {
        return heightMap.containsKey(p) ? heightMap.get(p) : 0;
    }
    private TreeNode rotateRight(TreeNode p) {
        TreeNode left = p.left;
        p.left = left.right;
        left.right = p;
        heightMap.put(p, Math.max(getHeight(p.left), getHeight(p.right)) + 1);
        heightMap.put(left,
                Math.max(getHeight(left.left), heightMap.get(p)) + 1);
        return left;
    }
    private TreeNode rotateLeft(TreeNode p) {
        TreeNode right = p.right;
        p.right = right.left;
        right.left = p;
        heightMap.put(p, Math.max(getHeight(p.left), getHeight(p.right)) + 1);
        heightMap
                .put(right, Math.max(getHeight(p), getHeight(right.right)) + 1);
        return right;
    }
    private TreeNode firstLeftThenRight(TreeNode p) {
        p.left = rotateLeft(p.left);
        p = rotateRight(p);
        return p;
    }
    private TreeNode firstRightThenLeft(TreeNode p) {
        p.right = rotateRight(p.right);
        p = rotateLeft(p);
        return p;
    }
    private void fixAfterInsertion(int key) {
        TreeNode p = root;
        while (!stack.isEmpty()) {
            p = stack.pop();
            int newHeight = Math.max(getHeight(p.left), getHeight(p.right)) + 1;
            if (heightMap.containsKey(p) && getHeight(p) > 1
                    && newHeight == getHeight(p)) {
                stack.clear();
                return;
            }
            heightMap.put(p, newHeight);
            int d = getHeight(p.left) - getHeight(p.right);
            if (Math.abs(d) <= 1) {
                continue;
            } else {
                if (d == 2) {
                    if (key - p.left.val < 0) {
                        p = rotateRight(p);
                    } else {
                        p = firstLeftThenRight(p);
                    }
                } else {
                    if (key - p.right.val > 0) {
                        p = rotateLeft(p);
                    } else {
                        p = firstRightThenLeft(p);
                    }
                }
                if (!stack.isEmpty()) {
                    if (key - stack.peek().val < 0) {
                        stack.peek().left = p;
                    } else {
                        stack.peek().right = p;
                    }
                }
            }
        }
        root = p;
    }
}
public class ConvertSortedArrayToBinarySearchTree {
    public TreeNode sortedArrayToBST_UsingAVL(int[] nums) {
        if (nums == null || nums.length == 0) {
            return null;
        }
        LeetCodeAVL avl = new LeetCodeAVL();
        for (int key : nums) {
            avl.put(key);
        }
        return avl.root;
    }
    public TreeNode sortedArrayToBST(int[] nums) {
        if (nums == null || nums.length == 0) {
            return null;
        }
        return buildFromSorted(0, nums.length-1, nums);
    }
    private  TreeNode buildFromSorted(int lo, int hi,int[] nums) {
        if (hi < lo)
            return null;

        int mid = (lo + hi) / 2;

        TreeNode left = null;
        if (lo < mid)
            left = buildFromSorted(lo, mid - 1, nums);
        TreeNode middle = new TreeNode(nums[mid]);
        if (left != null) {
            middle.left = left;
        }
        if (mid < hi) {
            TreeNode right = buildFromSorted(mid + 1, hi,nums);
            middle.right = right;
        }
        return middle;
    }
}

 寻找后继节点,最大节点,最小节点

public class InorderSuccessorInBST {
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if(p==null){
            return null;
        }
        if(getLastEntry(root)==p){
            return null;
        }
        if(p.right!=null){
            return getFirstEntry(p.right);
        }
        TreeNode parent=root;
        TreeNode temp=root;
        while(parent!=null){
            if(parent==p){
                break;
            }else if(p.val<parent.val){
                temp=parent;
                parent=parent.left;
            }else{
                parent=parent.right;
            }
        }
        return temp;
    }
    private TreeNode getLastEntry(TreeNode p){
        while(p.right!=null){
            p=p.right;
        }
        return p;
    }
    private TreeNode getFirstEntry(TreeNode p){
        while(p.left!=null){
            p=p.left;
        }
        return p;
    }
}

 红黑树的辅助工具

1.是一个二叉搜索树

2.每个节点要么是红的,要么是黑的

3.根节点是黑色的,并定义null 为 黑色

4.如果一个子结点是红色的,那么它的两个儿子都是黑色,且父节点也是黑色

5.对于任意一个结点而言,它到叶节点的每一条路径都包含相同数目的的黑色结点,称之为黑高

6.任意一棵以黑色节点为根的子树也必定是一颗红黑树

7.左右子树的高度最多是左右子树的两倍,则:若H(left)>H(right)  则 H(left)<=2*H(right)+1

-------------------------------------------------------------
无需调整的情况为:
   x为根节点,将X由红染黑,简称rootOver
   父节点P为黑色,BlackParentOver ,简称BpOver
仅仅需要考虑父节点P为红色的情况,由于性质4,爷爷的节点G必定为黑色可以分为下面三种情况
1.Y为红色,X可左可右:P,Y染黑,G染红  X 回溯至G
2.Y为黑色,X为右孩子:左旋P,X指向P,转换为3
3.Y为黑色,X为左孩子;P染黑,G染红,右旋G,结束

RBT的插入调整最多旋转2次

正在处理的节点X,也叫子节点
父节点P
爷爷节点G
叔叔节点Y
A3表示黑高为3的红黑树

 */
/*
利用 反射 输出map内部的变量信息,比如root
 */
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;

//红黑树的辅助工具
public class ReflectUtilForTreeMap {
    public static Class<?> entryClass;
    public static Field leftField;
    public static Field rightField;
    public static Class<?> treeMapClass;
    public static Field rootField;
    public static Field colorFiled;
    static{
        try {
            //因为红黑树里的属性都是私有的 ,因此我们编辑一个工具类来查看的属性,打开封装
            entryClass=Class.forName("java.util.TreeMap$Entry");
            leftField=entryClass.getDeclaredField("left");
            leftField.setAccessible(true);
            rightField=entryClass.getDeclaredField("right");
            rightField.setAccessible(true);
            treeMapClass=TreeMap.class;
            rootField=treeMapClass.getDeclaredField("root");
            rootField.setAccessible(true);
            colorFiled=entryClass.getDeclaredField("color");
            colorFiled.setAccessible(true);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    //打印节点
    private static <K,V> void printTreeNode(Map.Entry<K, V> p) throws Exception{
        boolean color=(Boolean) colorFiled.getBoolean(p);
        String colorStr="";
        if(color){
            colorStr="BLACK";
        }else{
            colorStr="RED";
        }
        System.out.print(p.getKey()+"-"+colorStr+"-"+p.getValue()+"  ");
    }
    /**
     * 层序输出JDK的红黑树
     */
    @SuppressWarnings("unchecked")
    public static <K,V> void levelOrderPrintTree(TreeMap<K,V> map) throws Exception{
        Map.Entry<K, V> root=(Map.Entry<K, V>) rootField.get(map);
        if(root==null){
            return;
        }
        Queue<Map.Entry<K, V>> queue=new LinkedList<Map.Entry<K, V>>();
        queue.offer(root);
        int preCount=1; //上一层的数量
        int pCount=0;   //下一层的计数器
        while(!queue.isEmpty()){
            Map.Entry<K, V> p=queue.poll();
            preCount--;
            printTreeNode(p);
            if((Map.Entry<K, V>)leftField.get(p)!=null){
                queue.offer((Map.Entry<K, V>)leftField.get(p));
                pCount++;
            }
            if((Map.Entry<K, V>)rightField.get(p)!=null){
                queue.offer((Map.Entry<K, V>)rightField.get(p));
                pCount++;
            }
            //经典的换行操作
            if(preCount==0){
                preCount=pCount;
                pCount=0;
                System.out.println();
            }
        }
        System.out.println("------------------------");
    }
}

红黑树的测试以及过程描述 

import org.junit.Test;

import java.util.TreeMap;

/*

 */
public class TestRBT {
    @Test
    public void testPrint() throws Exception{
        TreeMap<Integer,Integer> map=new TreeMap<Integer,Integer>();
        map.put(2, 2);
        map.put(4, 4);
        map.put(1, 1);
        map.put(6, 6);
        map.put(5, 5);
        map.put(3, 3);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
    }

    /*
         无需调整的情况为:
   x为根节点,将X由红染黑,简称rootOver
   父节点P为黑色,BlackParentOver ,简称BpOver

P为G的左孩子,三个左情况
1.Y为红色,X可左可右:P,Y染黑,G染红  X 回溯至G
2.Y为黑色,X为右孩子:左旋P,X指向P,转换为3
3.Y为黑色,X为左孩子;P染黑,G染红,右旋G,结束

P为G的右孩子,三种情况
1.Y为红,x可左可右,P,Y变黑,G变红,X变G
2.Y为黑,X为左孩子:右旋P,X变P
3.Y为黑,X为右孩子 G变红,P变黑,左旋G
     */
    @Test
    public void testInsert() throws Exception{
        TreeMap<Integer, Integer> map=new TreeMap<Integer, Integer>();
        // 依次插入:12,1,9,2,0,11,7,19,4,15,18,5
        // root,blackHeight=1;
        map.put(12, 12);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // bpOver
        map.put(1, 1);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // leftCase2 --> leftCase3
        map.put(9, 9);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // leftCase1 --> rootOver,blackHeight=2;
        map.put(2, 2);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // bpOver
        map.put(0, 0);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // bpOver
        map.put(11, 11);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // rightCase1 --> bpOver
        map.put(7, 7);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // bpOver
        map.put(19, 19);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // rightCase2 --> rightCase3
        Integer key4=4;
        map.put(key4, key4);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // rightCase1 --> bpOver
        map.put(15, 15);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // leftCase2 --> leftCase3
        map.put(18, 18);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // rightCase1 --> leftCase1 --> rootOver,blackHeight=3
        // case1可以执行多次
        Integer key5=5;
        map.put(key5, key5);
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
        // 插入余下的数字
        int[] others={14,13,10,16,6,3,8,17};
        for(int key:others){
            map.put(key, key);
        }
        ReflectUtilForTreeMap.levelOrderPrintTree(map);
    }
    @Test
    public void testRemove(){
        TreeMap<Integer, Integer> map=new TreeMap<Integer, Integer>();
        int[] array={12,1,9,2,0,11,7,19,4,15,18,5,14,13,10,16,6,3,8,17};
        for(int key:array){
            map.put(key, key);
        }
        // successor --> fix(p) | rightCase4-2 | p=null
        Integer key12=12;
        map.remove(key12);

        // successor --> replacement --> p=null --> fix(replacement) | redOver
        Integer key1=1;
        map.remove(key1);

        // successor --> fix(p) | leftCase2-2 --> redOver | p=null
        Integer key9=9;
        map.remove(key9);

        // successor --> fix(p) | rightCase2-2 --> redOver | p=null
        Integer key2=2;
        map.remove(key2);

        // p=null
        Integer key0=0;
        map.remove(key0);

        // replacement --> p=null --> fix(replacement) | redOver
        Integer key11=11;
        map.remove(key11);

        // replacement --> p=null --> fix(replacement) | redOver
        Integer key7=7;
        map.remove(key7);

        // fix(p) | rightCase4-1 | p=null
        Integer key19=19;
        map.remove(key19);

        // successor --> fix(p) | leftCase2-2 --> redOver | p=null
        Integer key4=4;
        map.remove(key4);

        // fix(p) | leftCase3 --> leftCase4-2 | p=null
        System.out.println("fix(p) | leftCase3 --> leftCase4-2 | p=null");
        Integer key15=15;
        map.remove(key15);

        // fix(p) | rightCase2-2 --> redOver | p=null
        Integer key18=18;
        map.remove(key18);

        // successor --> replacement --> p=null --> fix(replacement) | redOver
        Integer key5=5;
        map.remove(key5);

        // successor --> p=null
        System.out.println("successor --> p=null");
        Integer key14=14;
        map.remove(key14);

        // fix(p) | leftCase2-1 --> rightCase2-1 --> rootOver | p=null,blackHeight=2
        System.out.println("fix(p) | leftCase2-1 --> rightCase2-1 --> rootOver | p=null,blackHeight=2");
        Integer key13=13;
        map.remove(key13);

        // successor --> replacement --> p=null --> fix(replacement) | redOver
        Integer key10=10;
        map.remove(key10);

        // successor --> fix(p) | rightCase1 --> rightCase2-2 --> redOver | p=null
        Integer key16=16;
        map.remove(key16);

        // successor --> p=null
        Integer key6=6;
        map.remove(key6);

        // fix(p) | leftCase2-1 --> rootOver | p=null,blackHeight=1
        Integer key3=3;
        map.remove(key3);

        // replacement --> p=null --> fix(replacement) | rootOver&redOver
        Integer key8=8;
        map.remove(key8);

        // root=null,blackHeight=0
        Integer key17=17;
        map.remove(key17);

    }
}

 

package sxt.tree.warmup.warmup.bst.rbt;


import java.io.Serializable;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;



/*

1.是一个二叉搜索树

2.每个节点要么是红的,要么是黑的

3.根节点是黑色的,并定义null 为 黑色

4.如果一个子结点是红色的,那么它的两个儿子都是黑色,且父节点也是黑色

5.对于任意一个结点而言,它到叶节点的每一条路径都包含相同数目的的黑色结点,称之为黑高

6.任意一棵以黑色节点为根的子树也必定是一颗红黑树

7.左右子树的高度最多是左右子树的两倍,则:若H(left)>H(right)  则 H(left)<=2*H(right)+1

-------------------------------------------------------------
无需调整的情况为:
   x为根节点,将X由红染黑,简称rootOver
   父节点P为黑色,BlackParentOver ,简称BpOver
仅仅需要考虑父节点P为红色的情况,由于性质4,爷爷的节点G必定为黑色可以分为下面三种情况
1.Y为红色,X可左可右:P,Y染黑,G染红  X 回溯至G
2.Y为黑色,X为右孩子:左旋P,X指向P,转换为3
3.Y为黑色,X为左孩子;P染黑,G染红,右旋G,结束

RBT的插入调整最多旋转2次

正在处理的节点X,也叫子节点
父节点P
爷爷节点G
叔叔节点Y
A3表示黑高为3的红黑树

 */


public class TreeMap<K,V>
        extends AbstractMap<K,V>
        implements NavigableMap<K,V>, Cloneable, Serializable
{

    private final Comparator<? super K> comparator;   // 比较器

    private transient Entry<K,V> root;        //根节点

    private transient int size = 0;              //  集合大小

    private transient int modCount = 0;          //    修改次数

    private Collection<V> values;               //

    //构造器1
    public TreeMap() {
        comparator = null;
    }
    //构造器2
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
    //构造器3
    public TreeMap(Map<? extends K, ? extends V> m) {
        comparator = null;
        putAll(m);
    }
    //构造器4
    public TreeMap(SortedMap<K, ? extends V> m) {
        comparator = m.comparator();
        try {
            buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }
    }

    public int size() {
        return size;
    }


    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }


    public boolean containsValue(Object value) {
        for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
            if (valEquals(value, e.value))
                return true;
        return false;
    }


    public V get(Object key) {
        Entry<K,V> p = getEntry(key);
        return (p==null ? null : p.value);
    }

    public Comparator<? super K> comparator() {
        return comparator;
    }


    public K firstKey() {
        return key(getFirstEntry());
    }

    public K lastKey() {
        return key(getLastEntry());
    }

/*
Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。
instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
instanceof关键字的作用是判断一个对象是否是一个具体类的实例,
我们在重写equals方法中要先判断是否是同一对象,之后再判断一个对象是否是另一个的实例,
如果是判断各个属性值以判断是否是同一对象,不是一定不是同一对象。

 */


    public void putAll(Map<? extends K, ? extends V> map) {
        int mapSize = map.size();
        //map  是否是SortMap的一个子类,map的规模不为0
        if (size==0 && mapSize!=0 && map instanceof SortedMap) {
            Comparator<?> c = ((SortedMap<?,?>)map).comparator();
            if (c == comparator || (c != null && c.equals(comparator))) {
                ++modCount;
                try {
                    buildFromSorted(mapSize, map.entrySet().iterator(),
                            null, null);
                } catch (java.io.IOException cannotHappen) {
                } catch (ClassNotFoundException cannotHappen) {
                }
                return;
            }
        }
        super.putAll(map);
    }

    final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
        Comparable<? super K> k = (Comparable<? super K>) key;
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }

    final Entry<K,V> getEntryUsingComparator(Object key) {
        @SuppressWarnings("unchecked")
        K k = (K) key;
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            Entry<K,V> p = root;
            while (p != null) {
                int cmp = cpr.compare(k, p.key);
                if (cmp < 0)
                    p = p.left;
                else if (cmp > 0)
                    p = p.right;
                else
                    return p;
            }
        }
        return null;
    }


    final Entry<K,V> getCeilingEntry(K key) {
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = compare(key, p.key);
            if (cmp < 0) {
                if (p.left != null)
                    p = p.left;
                else
                    return p;
            } else if (cmp > 0) {
                if (p.right != null) {
                    p = p.right;
                } else {
                    Entry<K,V> parent = p.parent;
                    Entry<K,V> ch = p;
                    while (parent != null && ch == parent.right) {
                        ch = parent;
                        parent = parent.parent;
                    }
                    return parent;
                }
            } else
                return p;
        }
        return null;
    }


    final Entry<K,V> getFloorEntry(K key) {
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = compare(key, p.key);
            if (cmp > 0) {
                if (p.right != null)
                    p = p.right;
                else
                    return p;
            } else if (cmp < 0) {
                if (p.left != null) {
                    p = p.left;
                } else {
                    Entry<K,V> parent = p.parent;
                    Entry<K,V> ch = p;
                    while (parent != null && ch == parent.left) {
                        ch = parent;
                        parent = parent.parent;
                    }
                    return parent;
                }
            } else
                return p;

        }
        return null;
    }


    final Entry<K,V> getHigherEntry(K key) {
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = compare(key, p.key);
            if (cmp < 0) {
                if (p.left != null)
                    p = p.left;
                else
                    return p;
            } else {
                if (p.right != null) {
                    p = p.right;
                } else {
                    Entry<K,V> parent = p.parent;
                    Entry<K,V> ch = p;
                    while (parent != null && ch == parent.right) {
                        ch = parent;
                        parent = parent.parent;
                    }
                    return parent;
                }
            }
        }
        return null;
    }


    final Entry<K,V> getLowerEntry(K key) {
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = compare(key, p.key);
            if (cmp > 0) {
                if (p.right != null)
                    p = p.right;
                else
                    return p;
            } else {
                if (p.left != null) {
                    p = p.left;
                } else {
                    Entry<K,V> parent = p.parent;
                    Entry<K,V> ch = p;
                    while (parent != null && ch == parent.left) {
                        ch = parent;
                        parent = parent.parent;
                    }
                    return parent;
                }
            }
        }
        return null;
    }


    //清理
    public void clear() {
        modCount++;
        size = 0;
        root = null;
    }

   //克隆
    public Object clone() {
        TreeMap<?,?> clone;
        try {
            clone = (TreeMap<?,?>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e);
        }

        // Put clone into "virgin" state (except for comparator)
        clone.root = null;
        clone.size = 0;
        clone.modCount = 0;
        clone.entrySet = null;
        clone.navigableKeySet = null;
        clone.descendingMap = null;

        // Initialize clone with our mappings
        try {
            clone.buildFromSorted(size, entrySet().iterator(), null, null);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }

        return clone;
    }


    public Map.Entry<K,V> firstEntry() {
        return exportEntry(getFirstEntry());
    }

    public Map.Entry<K,V> lastEntry() {
        return exportEntry(getLastEntry());
    }


    public Map.Entry<K,V> pollFirstEntry() {
        Entry<K,V> p = getFirstEntry();
        Map.Entry<K,V> result = exportEntry(p);
        if (p != null)
            deleteEntry(p);
        return result;
    }


    public Map.Entry<K,V> pollLastEntry() {
        Entry<K,V> p = getLastEntry();
        Map.Entry<K,V> result = exportEntry(p);
        if (p != null)
            deleteEntry(p);
        return result;
    }


    public Map.Entry<K,V> lowerEntry(K key) {
        return exportEntry(getLowerEntry(key));
    }


    public K lowerKey(K key) {
        return keyOrNull(getLowerEntry(key));
    }


    public Map.Entry<K,V> floorEntry(K key) {
        return exportEntry(getFloorEntry(key));
    }


    public K floorKey(K key) {
        return keyOrNull(getFloorEntry(key));
    }


    public Map.Entry<K,V> ceilingEntry(K key) {
        return exportEntry(getCeilingEntry(key));
    }


    public K ceilingKey(K key) {
        return keyOrNull(getCeilingEntry(key));
    }


    public Map.Entry<K,V> higherEntry(K key) {
        return exportEntry(getHigherEntry(key));
    }


    public K higherKey(K key) {
        return keyOrNull(getHigherEntry(key));
    }

    private transient EntrySet entrySet;

    private transient KeySet<K> navigableKeySet;

    private transient NavigableMap<K,V> descendingMap;

    public Set<K> keySet() {
        return navigableKeySet();
    }


    public NavigableSet<K> navigableKeySet() {
        KeySet<K> nks = navigableKeySet;
        return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this));
    }


    public NavigableSet<K> descendingKeySet() {
        return descendingMap().navigableKeySet();
    }


    public Collection<V> values() {
        Collection<V> vs = values;
        if (vs == null) {
            vs = new Values();
            values = vs;
        }
        return vs;
    }

    public Set<Map.Entry<K,V>> entrySet() {
        EntrySet es = entrySet;
        return (es != null) ? es : (entrySet = new EntrySet());
    }

    public NavigableMap<K, V> descendingMap() {
        NavigableMap<K, V> km = descendingMap;
        return (km != null) ? km :
                (descendingMap = new DescendingSubMap<>(this,
                        true, null, true,
                        true, null, true));
    }

    public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
                                    K toKey,   boolean toInclusive) {
        return new AscendingSubMap<>(this,
                false, fromKey, fromInclusive,
                false, toKey,   toInclusive);
    }

    public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
        return new AscendingSubMap<>(this,
                true,  null,  true,
                false, toKey, inclusive);
    }

    public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
        return new AscendingSubMap<>(this,
                false, fromKey, inclusive,
                true,  null,    true);
    }

    public SortedMap<K,V> subMap(K fromKey, K toKey) {
        return subMap(fromKey, true, toKey, false);
    }

    public SortedMap<K,V> headMap(K toKey) {
        return headMap(toKey, false);
    }

    public SortedMap<K,V> tailMap(K fromKey) {
        return tailMap(fromKey, true);
    }

    @Override
    public boolean replace(K key, V oldValue, V newValue) {
        Entry<K,V> p = getEntry(key);
        if (p!=null && Objects.equals(oldValue, p.value)) {
            p.value = newValue;
            return true;
        }
        return false;
    }

    @Override
    public V replace(K key, V value) {
        Entry<K,V> p = getEntry(key);
        if (p!=null) {
            V oldValue = p.value;
            p.value = value;
            return oldValue;
        }
        return null;
    }

    @Override
    public void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        int expectedModCount = modCount;
        for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {
            action.accept(e.key, e.value);

            if (expectedModCount != modCount) {
                throw new ConcurrentModificationException();
            }
        }
    }

    @Override
    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
        Objects.requireNonNull(function);
        int expectedModCount = modCount;

        for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {
            e.value = function.apply(e.key, e.value);

            if (expectedModCount != modCount) {
                throw new ConcurrentModificationException();
            }
        }
    }

    // View class support

    class Values extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return new ValueIterator(getFirstEntry());
        }

        public int size() {
            return TreeMap.this.size();
        }

        public boolean contains(Object o) {
            return TreeMap.this.containsValue(o);
        }

        public boolean remove(Object o) {
            for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
                if (valEquals(e.getValue(), o)) {
                    deleteEntry(e);
                    return true;
                }
            }
            return false;
        }

        public void clear() {
            TreeMap.this.clear();
        }

        public Spliterator<V> spliterator() {
            return new ValueSpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
        }
    }

    class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator(getFirstEntry());
        }

        public boolean contains(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
            Object value = entry.getValue();
            Entry<K,V> p = getEntry(entry.getKey());
            return p != null && valEquals(p.getValue(), value);
        }

        public boolean remove(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
            Object value = entry.getValue();
            Entry<K,V> p = getEntry(entry.getKey());
            if (p != null && valEquals(p.getValue(), value)) {
                deleteEntry(p);
                return true;
            }
            return false;
        }

        public int size() {
            return TreeMap.this.size();
        }

        public void clear() {
            TreeMap.this.clear();
        }

        public Spliterator<Map.Entry<K,V>> spliterator() {
            return new EntrySpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
        }
    }



    Iterator<K> keyIterator() {
        return new KeyIterator(getFirstEntry());
    }

    Iterator<K> descendingKeyIterator() {
        return new DescendingKeyIterator(getLastEntry());
    }




    static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
        private final NavigableMap<E, ?> m;
        KeySet(NavigableMap<E,?> map) { m = map; }

        public Iterator<E> iterator() {
            if (m instanceof TreeMap)
                return ((TreeMap<E,?>)m).keyIterator();
            else
                return ((NavigableSubMap<E,?>)m).keyIterator();
        }

        public Iterator<E> descendingIterator() {
            if (m instanceof TreeMap)
                return ((TreeMap<E,?>)m).descendingKeyIterator();
            else
                return ((NavigableSubMap<E,?>)m).descendingKeyIterator();
        }

        public int size() { return m.size(); }
        public boolean isEmpty() { return m.isEmpty(); }
        public boolean contains(Object o) { return m.containsKey(o); }
        public void clear() { m.clear(); }
        public E lower(E e) { return m.lowerKey(e); }
        public E floor(E e) { return m.floorKey(e); }
        public E ceiling(E e) { return m.ceilingKey(e); }
        public E higher(E e) { return m.higherKey(e); }
        public E first() { return m.firstKey(); }
        public E last() { return m.lastKey(); }
        public Comparator<? super E> comparator() { return m.comparator(); }
        public E pollFirst() {
            Map.Entry<E,?> e = m.pollFirstEntry();
            return (e == null) ? null : e.getKey();
        }
        public E pollLast() {
            Map.Entry<E,?> e = m.pollLastEntry();
            return (e == null) ? null : e.getKey();
        }
        public boolean remove(Object o) {
            int oldSize = size();
            m.remove(o);
            return size() != oldSize;
        }
        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                                      E toElement,   boolean toInclusive) {
            return new KeySet<>(m.subMap(fromElement, fromInclusive,
                    toElement,   toInclusive));
        }
        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
            return new KeySet<>(m.headMap(toElement, inclusive));
        }
        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
            return new KeySet<>(m.tailMap(fromElement, inclusive));
        }
        public SortedSet<E> subSet(E fromElement, E toElement) {
            return subSet(fromElement, true, toElement, false);
        }
        public SortedSet<E> headSet(E toElement) {
            return headSet(toElement, false);
        }
        public SortedSet<E> tailSet(E fromElement) {
            return tailSet(fromElement, true);
        }
        public NavigableSet<E> descendingSet() {
            return new KeySet<>(m.descendingMap());
        }

        public Spliterator<E> spliterator() {
            return keySpliteratorFor(m);
        }
    }



    abstract class PrivateEntryIterator<T> implements Iterator<T> {
        Entry<K,V> next;
        Entry<K,V> lastReturned;
        int expectedModCount;

        PrivateEntryIterator(Entry<K,V> first) {
            expectedModCount = modCount;
            lastReturned = null;
            next = first;
        }

        public final boolean hasNext() {
            return next != null;
        }

        final Entry<K,V> nextEntry() {
            Entry<K,V> e = next;
            if (e == null)
                throw new NoSuchElementException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            next = successor(e);
            lastReturned = e;
            return e;
        }

        final Entry<K,V> prevEntry() {
            Entry<K,V> e = next;
            if (e == null)
                throw new NoSuchElementException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            next = predecessor(e);
            lastReturned = e;
            return e;
        }

        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            // deleted entries are replaced by their successors
            if (lastReturned.left != null && lastReturned.right != null)
                next = lastReturned;
            deleteEntry(lastReturned);
            expectedModCount = modCount;
            lastReturned = null;
        }
    }

    final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
        EntryIterator(Entry<K,V> first) {
            super(first);
        }
        public Map.Entry<K,V> next() {
            return nextEntry();
        }
    }

    final class ValueIterator extends PrivateEntryIterator<V> {
        ValueIterator(Entry<K,V> first) {
            super(first);
        }
        public V next() {
            return (V)nextEntry().value;
        }
    }

    final class KeyIterator extends PrivateEntryIterator<K> {
        KeyIterator(Entry<K,V> first) {
            super(first);
        }
        public K next() {
            return (K) nextEntry().key;
        }
    }

    final class DescendingKeyIterator extends PrivateEntryIterator<K> {
        DescendingKeyIterator(Entry<K,V> first) {
            super(first);
        }
        public K next() {
            return (K) prevEntry().key;
        }
        public void remove() {
            if (lastReturned == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            deleteEntry(lastReturned);
            lastReturned = null;
            expectedModCount = modCount;
        }
    }

//    该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
//unchecked     执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。
    @SuppressWarnings("unchecked")
    final int compare(Object k1, Object k2) {
        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
                : comparator.compare((K)k1, (K)k2);
        //其中,compareTo在不明确排序类型标准时,无法进行比较。因此会报错:
    }


    static final boolean valEquals(Object o1, Object o2) {
        return (o1==null ? o2==null : o1.equals(o2));
    }


    static <K,V> Map.Entry<K,V> exportEntry(Entry<K,V> e) {
        return (e == null) ? null :
                new SimpleImmutableEntry<>(e);
    }


    static <K,V> K keyOrNull(Entry<K,V> e) {
        return (e == null) ? null : e.key;
    }


    static <K> K key(Entry<K,?> e) {
        if (e==null)
            throw new NoSuchElementException();
        return e.key;
    }



    private static final Object UNBOUNDED = new Object();

    abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
            implements NavigableMap<K,V>, Serializable {
        private static final long serialVersionUID = -2102997345730753016L;
        /**
         * The backing map.
         */
        final TreeMap<K,V> m;

        final K lo, hi;
        final boolean fromStart, toEnd;
        final boolean loInclusive, hiInclusive;

        NavigableSubMap(TreeMap<K,V> m,
                        boolean fromStart, K lo, boolean loInclusive,
                        boolean toEnd, K hi, boolean hiInclusive) {
            if (!fromStart && !toEnd) {
                if (m.compare(lo, hi) > 0)
                    throw new IllegalArgumentException("fromKey > toKey");
            } else {
                if (!fromStart) // type check
                    m.compare(lo, lo);
                if (!toEnd)
                    m.compare(hi, hi);
            }

            this.m = m;
            this.fromStart = fromStart;
            this.lo = lo;
            this.loInclusive = loInclusive;
            this.toEnd = toEnd;
            this.hi = hi;
            this.hiInclusive = hiInclusive;
        }

        // internal utilities

        final boolean tooLow(Object key) {
            if (!fromStart) {
                int c = m.compare(key, lo);
                if (c < 0 || (c == 0 && !loInclusive))
                    return true;
            }
            return false;
        }

        final boolean tooHigh(Object key) {
            if (!toEnd) {
                int c = m.compare(key, hi);
                if (c > 0 || (c == 0 && !hiInclusive))
                    return true;
            }
            return false;
        }

        final boolean inRange(Object key) {
            return !tooLow(key) && !tooHigh(key);
        }

        final boolean inClosedRange(Object key) {
            return (fromStart || m.compare(key, lo) >= 0)
                    && (toEnd || m.compare(hi, key) >= 0);
        }

        final boolean inRange(Object key, boolean inclusive) {
            return inclusive ? inRange(key) : inClosedRange(key);
        }

        /*
         * Absolute versions of relation operations.
         * Subclasses map to these using like-named "sub"
         * versions that invert senses for descending maps
         */

        final TreeMap.Entry<K,V> absLowest() {
            TreeMap.Entry<K,V> e =
                    (fromStart ?  m.getFirstEntry() :
                            (loInclusive ? m.getCeilingEntry(lo) :
                                    m.getHigherEntry(lo)));
            return (e == null || tooHigh(e.key)) ? null : e;
        }

        final TreeMap.Entry<K,V> absHighest() {
            TreeMap.Entry<K,V> e =
                    (toEnd ?  m.getLastEntry() :
                            (hiInclusive ?  m.getFloorEntry(hi) :
                                    m.getLowerEntry(hi)));
            return (e == null || tooLow(e.key)) ? null : e;
        }

        final TreeMap.Entry<K,V> absCeiling(K key) {
            if (tooLow(key))
                return absLowest();
            TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
            return (e == null || tooHigh(e.key)) ? null : e;
        }

        final TreeMap.Entry<K,V> absHigher(K key) {
            if (tooLow(key))
                return absLowest();
            TreeMap.Entry<K,V> e = m.getHigherEntry(key);
            return (e == null || tooHigh(e.key)) ? null : e;
        }

        final TreeMap.Entry<K,V> absFloor(K key) {
            if (tooHigh(key))
                return absHighest();
            TreeMap.Entry<K,V> e = m.getFloorEntry(key);
            return (e == null || tooLow(e.key)) ? null : e;
        }

        final TreeMap.Entry<K,V> absLower(K key) {
            if (tooHigh(key))
                return absHighest();
            TreeMap.Entry<K,V> e = m.getLowerEntry(key);
            return (e == null || tooLow(e.key)) ? null : e;
        }

        /** Returns the absolute high fence for ascending traversal */
        final TreeMap.Entry<K,V> absHighFence() {
            return (toEnd ? null : (hiInclusive ?
                    m.getHigherEntry(hi) :
                    m.getCeilingEntry(hi)));
        }

        /** Return the absolute low fence for descending traversal  */
        final TreeMap.Entry<K,V> absLowFence() {
            return (fromStart ? null : (loInclusive ?
                    m.getLowerEntry(lo) :
                    m.getFloorEntry(lo)));
        }

        // Abstract methods defined in ascending vs descending classes
        // These relay to the appropriate absolute versions

        abstract TreeMap.Entry<K,V> subLowest();
        abstract TreeMap.Entry<K,V> subHighest();
        abstract TreeMap.Entry<K,V> subCeiling(K key);
        abstract TreeMap.Entry<K,V> subHigher(K key);
        abstract TreeMap.Entry<K,V> subFloor(K key);
        abstract TreeMap.Entry<K,V> subLower(K key);

        /** Returns ascending iterator from the perspective of this submap */
        abstract Iterator<K> keyIterator();

        abstract Spliterator<K> keySpliterator();

        /** Returns descending iterator from the perspective of this submap */
        abstract Iterator<K> descendingKeyIterator();

        // public methods

        public boolean isEmpty() {
            return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty();
        }

        public int size() {
            return (fromStart && toEnd) ? m.size() : entrySet().size();
        }

        public final boolean containsKey(Object key) {
            return inRange(key) && m.containsKey(key);
        }

        public final V put(K key, V value) {
            if (!inRange(key))
                throw new IllegalArgumentException("key out of range");
            return m.put(key, value);
        }

        public final V get(Object key) {
            return !inRange(key) ? null :  m.get(key);
        }

        public final V remove(Object key) {
            return !inRange(key) ? null : m.remove(key);
        }

        public final Entry<K,V> ceilingEntry(K key) {
            return exportEntry(subCeiling(key));
        }

        public final K ceilingKey(K key) {
            return keyOrNull(subCeiling(key));
        }

        public final Entry<K,V> higherEntry(K key) {
            return exportEntry(subHigher(key));
        }

        public final K higherKey(K key) {
            return keyOrNull(subHigher(key));
        }

        public final Entry<K,V> floorEntry(K key) {
            return exportEntry(subFloor(key));
        }

        public final K floorKey(K key) {
            return keyOrNull(subFloor(key));
        }

        public final Entry<K,V> lowerEntry(K key) {
            return exportEntry(subLower(key));
        }

        public final K lowerKey(K key) {
            return keyOrNull(subLower(key));
        }

        public final K firstKey() {
            return key(subLowest());
        }

        public final K lastKey() {
            return key(subHighest());
        }

        public final Entry<K,V> firstEntry() {
            return exportEntry(subLowest());
        }

        public final Entry<K,V> lastEntry() {
            return exportEntry(subHighest());
        }

        public final Entry<K,V> pollFirstEntry() {
            TreeMap.Entry<K,V> e = subLowest();
            Entry<K,V> result = exportEntry(e);
            if (e != null)
                m.deleteEntry(e);
            return result;
        }

        public final Entry<K,V> pollLastEntry() {
            TreeMap.Entry<K,V> e = subHighest();
            Entry<K,V> result = exportEntry(e);
            if (e != null)
                m.deleteEntry(e);
            return result;
        }

        // Views
        transient NavigableMap<K,V> descendingMapView;
        transient EntrySetView entrySetView;
        transient KeySet<K> navigableKeySetView;

        public final NavigableSet<K> navigableKeySet() {
            KeySet<K> nksv = navigableKeySetView;
            return (nksv != null) ? nksv :
                    (navigableKeySetView = new KeySet<>(this));
        }

        public final Set<K> keySet() {
            return navigableKeySet();
        }

        public NavigableSet<K> descendingKeySet() {
            return descendingMap().navigableKeySet();
        }

        public final SortedMap<K,V> subMap(K fromKey, K toKey) {
            return subMap(fromKey, true, toKey, false);
        }

        public final SortedMap<K,V> headMap(K toKey) {
            return headMap(toKey, false);
        }

        public final SortedMap<K,V> tailMap(K fromKey) {
            return tailMap(fromKey, true);
        }

        // View classes

        abstract class EntrySetView extends AbstractSet<Entry<K,V>> {
            private transient int size = -1, sizeModCount;

            public int size() {
                if (fromStart && toEnd)
                    return m.size();
                if (size == -1 || sizeModCount != m.modCount) {
                    sizeModCount = m.modCount;
                    size = 0;
                    Iterator<?> i = iterator();
                    while (i.hasNext()) {
                        size++;
                        i.next();
                    }
                }
                return size;
            }

            public boolean isEmpty() {
                TreeMap.Entry<K,V> n = absLowest();
                return n == null || tooHigh(n.key);
            }

            public boolean contains(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Entry<?,?> entry = (Entry<?,?>) o;
                Object key = entry.getKey();
                if (!inRange(key))
                    return false;
                TreeMap.Entry<?,?> node = m.getEntry(key);
                return node != null &&
                        valEquals(node.getValue(), entry.getValue());
            }

            public boolean remove(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Entry<?,?> entry = (Entry<?,?>) o;
                Object key = entry.getKey();
                if (!inRange(key))
                    return false;
                TreeMap.Entry<K,V> node = m.getEntry(key);
                if (node!=null && valEquals(node.getValue(),
                        entry.getValue())) {
                    m.deleteEntry(node);
                    return true;
                }
                return false;
            }
        }

        /**
         * Iterators for SubMaps
         */
        abstract class SubMapIterator<T> implements Iterator<T> {
            TreeMap.Entry<K,V> lastReturned;
            TreeMap.Entry<K,V> next;
            final Object fenceKey;
            int expectedModCount;

            SubMapIterator(TreeMap.Entry<K,V> first,
                           TreeMap.Entry<K,V> fence) {
                expectedModCount = m.modCount;
                lastReturned = null;
                next = first;
                fenceKey = fence == null ? UNBOUNDED : fence.key;
            }

            public final boolean hasNext() {
                return next != null && next.key != fenceKey;
            }

            final TreeMap.Entry<K,V> nextEntry() {
                TreeMap.Entry<K,V> e = next;
                if (e == null || e.key == fenceKey)
                    throw new NoSuchElementException();
                if (m.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                next = successor(e);
                lastReturned = e;
                return e;
            }

            final TreeMap.Entry<K,V> prevEntry() {
                TreeMap.Entry<K,V> e = next;
                if (e == null || e.key == fenceKey)
                    throw new NoSuchElementException();
                if (m.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                next = predecessor(e);
                lastReturned = e;
                return e;
            }

            final void removeAscending() {
                if (lastReturned == null)
                    throw new IllegalStateException();
                if (m.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                // deleted entries are replaced by their successors
                if (lastReturned.left != null && lastReturned.right != null)
                    next = lastReturned;
                m.deleteEntry(lastReturned);
                lastReturned = null;
                expectedModCount = m.modCount;
            }

            final void removeDescending() {
                if (lastReturned == null)
                    throw new IllegalStateException();
                if (m.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                m.deleteEntry(lastReturned);
                lastReturned = null;
                expectedModCount = m.modCount;
            }

        }

        final class SubMapEntryIterator extends SubMapIterator<Entry<K,V>> {
            SubMapEntryIterator(TreeMap.Entry<K,V> first,
                                TreeMap.Entry<K,V> fence) {
                super(first, fence);
            }
            public Entry<K,V> next() {
                return nextEntry();
            }
            public void remove() {
                removeAscending();
            }
        }

        final class DescendingSubMapEntryIterator extends SubMapIterator<Entry<K,V>> {
            DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
                                          TreeMap.Entry<K,V> fence) {
                super(last, fence);
            }

            public Entry<K,V> next() {
                return prevEntry();
            }
            public void remove() {
                removeDescending();
            }
        }

        // Implement minimal Spliterator as KeySpliterator backup
        final class SubMapKeyIterator extends SubMapIterator<K>
                implements Spliterator<K> {
            SubMapKeyIterator(TreeMap.Entry<K,V> first,
                              TreeMap.Entry<K,V> fence) {
                super(first, fence);
            }
            public K next() {
                return (K) nextEntry().key;
            }
            public void remove() {
                removeAscending();
            }
            public Spliterator<K> trySplit() {
                return null;
            }
            public void forEachRemaining(Consumer<? super K> action) {
                while (hasNext())
                    action.accept(next());
            }
            public boolean tryAdvance(Consumer<? super K> action) {
                if (hasNext()) {
                    action.accept(next());
                    return true;
                }
                return false;
            }
            public long estimateSize() {
                return Long.MAX_VALUE;
            }
            public int characteristics() {
                return Spliterator.DISTINCT | Spliterator.ORDERED |
                        Spliterator.SORTED;
            }
            public final Comparator<? super K>  getComparator() {
                return NavigableSubMap.this.comparator();
            }
        }

        final class DescendingSubMapKeyIterator extends SubMapIterator<K>
                implements Spliterator<K> {
            DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last,
                                        TreeMap.Entry<K,V> fence) {
                super(last, fence);
            }
            public K next() {
                return (K)prevEntry().key;
            }
            public void remove() {
                removeDescending();
            }
            public Spliterator<K> trySplit() {
                return null;
            }
            public void forEachRemaining(Consumer<? super K> action) {
                while (hasNext())
                    action.accept(next());
            }
            public boolean tryAdvance(Consumer<? super K> action) {
                if (hasNext()) {
                    action.accept(next());
                    return true;
                }
                return false;
            }
            public long estimateSize() {
                return Long.MAX_VALUE;
            }
            public int characteristics() {
                return Spliterator.DISTINCT | Spliterator.ORDERED;
            }
        }
    }

    /**
     * @serial include
     */
    static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
        private static final long serialVersionUID = 912986545866124060L;

        AscendingSubMap(TreeMap<K,V> m,
                        boolean fromStart, K lo, boolean loInclusive,
                        boolean toEnd, K hi, boolean hiInclusive) {
            super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
        }

        public Comparator<? super K> comparator() {
            return m.comparator();
        }

        public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
                                        K toKey,   boolean toInclusive) {
            if (!inRange(fromKey, fromInclusive))
                throw new IllegalArgumentException("fromKey out of range");
            if (!inRange(toKey, toInclusive))
                throw new IllegalArgumentException("toKey out of range");
            return new AscendingSubMap<>(m,
                    false, fromKey, fromInclusive,
                    false, toKey,   toInclusive);
        }

        public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
            if (!inRange(toKey, inclusive))
                throw new IllegalArgumentException("toKey out of range");
            return new AscendingSubMap<>(m,
                    fromStart, lo,    loInclusive,
                    false,     toKey, inclusive);
        }

        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
            if (!inRange(fromKey, inclusive))
                throw new IllegalArgumentException("fromKey out of range");
            return new AscendingSubMap<>(m,
                    false, fromKey, inclusive,
                    toEnd, hi,      hiInclusive);
        }

        public NavigableMap<K,V> descendingMap() {
            NavigableMap<K,V> mv = descendingMapView;
            return (mv != null) ? mv :
                    (descendingMapView =
                            new DescendingSubMap<>(m,
                                    fromStart, lo, loInclusive,
                                    toEnd,     hi, hiInclusive));
        }

        Iterator<K> keyIterator() {
            return new SubMapKeyIterator(absLowest(), absHighFence());
        }

        Spliterator<K> keySpliterator() {
            return new SubMapKeyIterator(absLowest(), absHighFence());
        }

        Iterator<K> descendingKeyIterator() {
            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
        }

        final class AscendingEntrySetView extends EntrySetView {
            public Iterator<Entry<K,V>> iterator() {
                return new SubMapEntryIterator(absLowest(), absHighFence());
            }
        }

        public Set<Entry<K,V>> entrySet() {
            EntrySetView es = entrySetView;
            return (es != null) ? es : (entrySetView = new AscendingEntrySetView());
        }

        TreeMap.Entry<K,V> subLowest()       { return absLowest(); }
        TreeMap.Entry<K,V> subHighest()      { return absHighest(); }
        TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); }
        TreeMap.Entry<K,V> subHigher(K key)  { return absHigher(key); }
        TreeMap.Entry<K,V> subFloor(K key)   { return absFloor(key); }
        TreeMap.Entry<K,V> subLower(K key)   { return absLower(key); }
    }

    /**
     * @serial include
     */
    static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> {
        private static final long serialVersionUID = 912986545866120460L;
        DescendingSubMap(TreeMap<K,V> m,
                         boolean fromStart, K lo, boolean loInclusive,
                         boolean toEnd, K hi, boolean hiInclusive) {
            super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
        }

        private final Comparator<? super K> reverseComparator =
                Collections.reverseOrder(m.comparator);

        public Comparator<? super K> comparator() {
            return reverseComparator;
        }

        public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
                                        K toKey,   boolean toInclusive) {
            if (!inRange(fromKey, fromInclusive))
                throw new IllegalArgumentException("fromKey out of range");
            if (!inRange(toKey, toInclusive))
                throw new IllegalArgumentException("toKey out of range");
            return new DescendingSubMap<>(m,
                    false, toKey,   toInclusive,
                    false, fromKey, fromInclusive);
        }

        public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
            if (!inRange(toKey, inclusive))
                throw new IllegalArgumentException("toKey out of range");
            return new DescendingSubMap<>(m,
                    false, toKey, inclusive,
                    toEnd, hi,    hiInclusive);
        }

        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
            if (!inRange(fromKey, inclusive))
                throw new IllegalArgumentException("fromKey out of range");
            return new DescendingSubMap<>(m,
                    fromStart, lo, loInclusive,
                    false, fromKey, inclusive);
        }

        public NavigableMap<K,V> descendingMap() {
            NavigableMap<K,V> mv = descendingMapView;
            return (mv != null) ? mv :
                    (descendingMapView =
                            new AscendingSubMap<>(m,
                                    fromStart, lo, loInclusive,
                                    toEnd,     hi, hiInclusive));
        }

        Iterator<K> keyIterator() {
            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
        }

        Spliterator<K> keySpliterator() {
            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
        }

        Iterator<K> descendingKeyIterator() {
            return new SubMapKeyIterator(absLowest(), absHighFence());
        }

        final class DescendingEntrySetView extends EntrySetView {
            public Iterator<Entry<K,V>> iterator() {
                return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
            }
        }

        public Set<Entry<K,V>> entrySet() {
            EntrySetView es = entrySetView;
            return (es != null) ? es : (entrySetView = new DescendingEntrySetView());
        }

        TreeMap.Entry<K,V> subLowest()       { return absHighest(); }
        TreeMap.Entry<K,V> subHighest()      { return absLowest(); }
        TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); }
        TreeMap.Entry<K,V> subHigher(K key)  { return absLower(key); }
        TreeMap.Entry<K,V> subFloor(K key)   { return absCeiling(key); }
        TreeMap.Entry<K,V> subLower(K key)   { return absHigher(key); }
    }

    /**
     * This class exists solely for the sake of serialization
     * compatibility with previous releases of TreeMap that did not
     * support NavigableMap.  It translates an old-version SubMap into
     * a new-version AscendingSubMap. This class is never otherwise
     * used.
     *
     * @serial include
     */
    private class SubMap extends AbstractMap<K,V>
            implements SortedMap<K,V>, Serializable {
        private static final long serialVersionUID = -6520786458950516097L;
        private boolean fromStart = false, toEnd = false;
        private K fromKey, toKey;
        private Object readResolve() {
            return new AscendingSubMap<>(TreeMap.this,
                    fromStart, fromKey, true,
                    toEnd, toKey, false);
        }
        public Set<Entry<K,V>> entrySet() { throw new InternalError(); }
        public K lastKey() { throw new InternalError(); }
        public K firstKey() { throw new InternalError(); }
        public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); }
        public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); }
        public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); }
        public Comparator<? super K> comparator() { throw new InternalError(); }
    }


    // Red-black mechanics

    private static final boolean RED   = false;
    private static final boolean BLACK = true;




    static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;                //键
        V value;              //值
        Entry<K,V> left;   //左节点
        Entry<K,V> right;   // 右节点
        Entry<K,V> parent;   //双亲节点
        boolean color = BLACK;       // 默认颜色是黑色

      //构造器
        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }

       //返回 key
        public K getKey() {
            return key;
        }

        //返回 值 value
        public V getValue() {
            return value;
        }
       // 设置 值
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }
        //  判断键值是否相等
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;

            return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
        }
        //获取键值对的 哈希值
        public int hashCode() {
            int keyHash = (key==null ? 0 : key.hashCode());
            int valueHash = (value==null ? 0 : value.hashCode());
            return keyHash ^ valueHash;
        }
        //转换为String
        public String toString() {
            return key + "=" + value;
        }
    }

    //获取最左子树(即树的最小值)
    final Entry<K,V> getFirstEntry() {
        Entry<K,V> p = root;
        if (p != null)
            while (p.left != null)
                p = p.left;
        return p;
    }

    /*
    1. 当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,
    就可以用final进行修饰。final类中的成员变量可以根据需要设为final,
    但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

    2.使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个
    原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可
    能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了
    如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的,类的private方法会隐式地被指定为final方法。

    3. 修饰变量:对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如
    果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象

    final修饰其实是防止其被重新初始化 也就是被重新new 一个 或者被 = 赋值而已。

     */
    //获取最右子树,即最大节点
    final Entry<K,V> getLastEntry() {
        Entry<K,V> p = root;
        if (p != null)
            while (p.right != null)
                p = p.right;
        return p;
    }

   //返回指定节点的后继节点
    static <K,V> Entry<K,V> successor(Entry<K,V> t) {
        if (t == null)  // case1: t==null   返回空节点
            return null;
        else if (t.right != null) {// case2:  假如t存在右子树,返回右子树的最左节点作为后继节点
            Entry<K,V> p = t.right;
            while (p.left != null)
                p = p.left;
            return p;
        } else {           //case3: 一直回溯到有一个节点为他的父节点存在右子树,此时该父节点就为t的后继节点
            Entry<K,V> p = t.parent;
            Entry<K,V> ch = t;
            while (p != null && ch == p.right) { //寻找到p存在第一个右子树
                ch = p;             //依次往上回溯,父节点作为子节点
                p = p.parent;
            }//  最终 如果为右子树的最大节点  找不到 此时 p为null
            return p;
        }
    }
    // 返回  指定节点的前一个节点
    static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
        if (t == null)
            return null;
        else if (t.left != null) { //返回左子树的最大节点
            Entry<K,V> p = t.left;
            while (p.right != null)
                p = p.right;
            return p;
        } else {           //返回第一个有左子树的根节点
            Entry<K,V> p = t.parent;
            Entry<K,V> ch = t;
            while (p != null && ch == p.left) {
                ch = p;
                p = p.parent;
            }
            return p;
        }
    }
    //染色   空节点为黑色
    private static <K,V> boolean colorOf(Entry<K,V> p) {
        return (p == null ? BLACK : p.color);
    }
    //寻找该节点的父亲节点
    private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) {
        return (p == null ? null: p.parent);
    }
    //设置颜色
    private static <K,V> void setColor(Entry<K,V> p, boolean c) {
        if (p != null)
            p.color = c;
    }
    //返回左子树
    private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
        return (p == null) ? null: p.left;
    }
    //返回右子树
    private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) {
        return (p == null) ? null: p.right;
    }

//    左旋转
    private void rotateLeft(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> r = p.right;  //找到p的右子树为r
            p.right = r.left;        //将r的左子树令为p的右子树
            if (r.left != null)     //假如r的左子树不为空
                r.left.parent = p;    //将r的左子树的父亲指向p
            r.parent = p.parent;       // 将p的父亲节点作为r的父亲节点
            //将r添加到合适的子树上
            if (p.parent == null)      //如果说p的父亲为空,说明p是根节点
                root = r;             // 将r节点作为根节点
            else if (p.parent.left == p)  //否则假如p是其父亲节点的左子树
                p.parent.left = r;         //将r作为p父亲节点的左子树
            else
                p.parent.right = r;       // 否则将r 作为其父亲节点p的右子树
            r.left = p;                 // 将p作为r的左子树
            p.parent = r;               // p的父亲节点指向r
        }
    }

//   右旋转    与左旋转同理
    private void rotateRight(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> l = p.left;
            p.left = l.right;
            if (l.right != null) l.right.parent = p;
            l.parent = p.parent;
            if (p.parent == null)
                root = l;
            else if (p.parent.right == p)
                p.parent.right = l;
            else p.parent.left = l;
            l.right = p;
            p.parent = l;
        }
    }

    //进行 插入操作
    public V put(K key, V value) {
        Entry<K,V> t = root;  // 获取根节点
        if (t == null) {  //如果说根节点为空,我们直接生成一个新的树
            compare(key, key);

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
       //新建一个比较器
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)  //如果比根节点小,找左子树
                    t = t.left;
                else if (cmp > 0)  //如果比根节点da ,找右子树
                    t = t.right;
                else          //和根节点相等 ,更新 值
                    return t.setValue(value);
            } while (t != null);
        }
        else { //如果比较器为空
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }
    /*
1.红黑树是一棵平衡二叉搜索树,其中序遍历单调不减。
2.节点是红色或黑色。
3.根节点是黑色。
4.每个叶节点(也有称外部节点的,目的是将红黑树变为真二叉树,即 NULL 节点,空节点)是黑色的。
5.每个红色节点的两个子节点都是黑色。 (换句话说,从每个叶子到根的所有路径上不能有两个连续的
红色节点)
6.从根节点到每个叶子的所有路径都包含相同数目的黑色节点(这个数值叫做黑高度)。
     */
/*
插入
            G
         p     Y
      x
     A3  B3   C2  D2
     树为空为黑色

     无需调整的情况为:
   x为根节点,将X由红染黑,简称rootOver
   父节点P为黑色,BlackParentOver ,简称BpOver

P为G的左孩子,三个左情况
1.Y为红色,X可左可右:P,Y染黑,G染红  X 回溯至G
2.Y为黑色,X为右孩子:左旋P,X指向P,转换为3
3.Y为黑色,X为左孩子;P染黑,G染红,右旋G,结束

P为G的右孩子,三种情况
1.Y为红,x可左可右,P,Y变黑,G变红,X变G
2.Y为黑,X为左孩子:右旋P,X变P
3.Y为黑,X为右孩子 G变红,P变黑,左旋G

 */
    //  插入之后要进行调整
    private void fixAfterInsertion(Entry<K,V> x) {
        //每当新插入一个节点时,我们将它的颜色设置为红色
        x.color = RED;

        //规则 不能有两个连续的节点为红色 ,其判断条件就是 x的父节点不为红色时就终止
        while (x != null && x != root && x.parent.color == RED) {
            //红黑树在最坏情况下每次回溯两层,这就是为什么插入比AVL的快的原因
            if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { //p为G的左孩子,假如x的父亲节点为左子树
                Entry<K,V> y = rightOf(parentOf(parentOf(x))); //取得Y为G的右孩子(叔叔节点),取得x的叔叔节点
                if (colorOf(y) == RED) {  //叔叔Y为红色,x可左可右
                    setColor(parentOf(x), BLACK);//P染黑
                    setColor(y, BLACK);   //Y染黑
                    setColor(parentOf(parentOf(x)), RED); //G染红
                    x = parentOf(parentOf(x));  //将x回溯为G
                } else {   //Y 是黑色
                    if (x == rightOf(parentOf(x))) {  //x是p的右孩子
                        x = parentOf(x);            //  x指向P
                        rotateLeft(x);              //左旋p
                    }
                    //x是p的左孩子
                    setColor(parentOf(x), BLACK);   //p染黑
                    setColor(parentOf(parentOf(x)), RED);   //G染红
                    rotateRight(parentOf(parentOf(x)));   //右旋G
                }
            } else {// p为G右孩子
                Entry<K,V> y = leftOf(parentOf(parentOf(x)));
                if (colorOf(y) == RED) {
                    setColor(parentOf(x), BLACK);
                    setColor(y, BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    x = parentOf(parentOf(x));
                } else {
                    if (x == leftOf(parentOf(x))) {
                        x = parentOf(x);
                        rotateRight(x);
                    }
                    setColor(parentOf(x), BLACK);
                    setColor(parentOf(parentOf(x)), RED);
                    rotateLeft(parentOf(parentOf(x)));
                }
            }
        }
        root.color = BLACK;
    }

//    删除节点p,对其调整平衡
    private void deleteEntry(Entry<K,V> p) {
        modCount++;
        size--;

//        假如的p有两个孩子
        if (p.left != null && p.right != null) {
            Entry<K,V> s = successor(p); //找到p的后继节点,令后继节点等于要删除的节点p,删除后继节点
            p.key = s.key;
            p.value = s.value;
            p = s;
        }

        // 新建一个替代节点,左子树不为空为左孩子,右子树不为空,为右孩子
        Entry<K,V> replacement = (p.left != null ? p.left : p.right);

        //case1:  替代节点存在左子树或者右子树
        if (replacement != null) {
            //确定p为左子树 还是右子树 还是根节点
            replacement.parent = p.parent;
            if (p.parent == null)
                root = replacement;
            else if (p == p.parent.left)
                p.parent.left  = replacement;
            else
                p.parent.right = replacement;

            // 将p全部置为空
            p.left = p.right = p.parent = null;

            // 假如p的颜色为黑色,需要对整个树进行调整
            if (p.color == BLACK)
                fixAfterDeletion(replacement);
        } else if (p.parent == null) { //case2:替代节点没有子树,且p.parent为空,只有一个节点,将根节点置为空
            root = null;
        } else { //case3: 假如没有孩子
            if (p.color == BLACK)
                fixAfterDeletion(p);

            //p的颜色为红色,且p的父节点不为空
            if (p.parent != null) {
                if (p == p.parent.left)
                    p.parent.left = null;  // 如果p是左子树,将左子树置为空
                else if (p == p.parent.right)
                    p.parent.right = null;    //如果p是右子树将右子树置为空
                p.parent = null;              //将p的父亲的引用置为空
            }
        }
    }




    public V remove(Object key) {
        Entry<K,V> p = getEntry(key);
        if (p == null)
            return null;

        V oldValue = p.value;
        deleteEntry(p);
        return oldValue;
    }


    /*
   删除
         P
       X     S
     A2   LN  RN
          c3   D3
需要删除的节点为红色,直接删除
其他无需调整的情况为
当前X为根节点,无论root什么颜色,都将root染黑    rootover
当前X为红色,将X染黑,结束,redOver

删除左孩子X,分为四种情况
1 .S为红色,S染黑,P染红,左旋P
2 .S为黑色,LN,RN也为 黑色 : S染红,X回溯至  P
3 .S为黑色,红LN,黑RN : LN染黑,S染红,右旋S
4 .S为黑色,任意颜色LN,红色的RN:S变为P的 颜色,P和S染黑,左旋P
红黑树删除操作最多是三次
          P
       S    x
    LN  RN
删除右孩子X
1 .S为红色,S染黑,P染红,右旋P
2 .S为黑色,LN,RN也为 黑色 : S染红,X回溯至  P
3 .S为黑色,红LN,黑RN : LN染黑,S染红,左旋S
4 .S为黑色,任意颜色LN,红色的RN:S变为P的 颜色,P和S染黑,右旋P
    */
    private void fixAfterDeletion(Entry<K,V> x) {
        while (x != root && colorOf(x) == BLACK) {
            if (x == leftOf(parentOf(x))) {    // x 是 p的左孩子
                Entry<K,V> sib = rightOf(parentOf(x)); //取得兄弟节点s
                if (colorOf(sib) == RED) {  //s为红色
                    setColor(sib, BLACK);    // s染黑
                    setColor(parentOf(x), RED); //p染红
                    rotateLeft(parentOf(x));   //左旋P
                    sib = rightOf(parentOf(x)); //  原来的Ln 成为新的s
                }

                if (colorOf(leftOf(sib))  == BLACK &&
                        colorOf(rightOf(sib)) == BLACK) { //  S LN RN 均为黑色的
                    setColor(sib, RED);  //将s染红
                    x = parentOf(x);    //x回溯至p
                } else {
                    //情况三
                    if (colorOf(rightOf(sib)) == BLACK) {   //S为黑色,Ln为红色,RN为黑色
                        setColor(leftOf(sib), BLACK);  //ln染黑
                        setColor(sib, RED);      //S染红
                        rotateRight(sib);       //右旋S
                        sib = rightOf(parentOf(x));   //S 指向ln
                    }
                    // 情况四  s为黑色,p可红可黑,RN为红色,Ln可红可黑
                    setColor(sib, colorOf(parentOf(x))); // s颜色设置与P相同
                    setColor(parentOf(x), BLACK);       // P染黑
                    setColor(rightOf(sib), BLACK);       //Rn染黑
                    rotateLeft(parentOf(x));           //左旋P
                    x = root;                      // 回溯至根节点
                }
            } else {

                Entry<K,V> sib = leftOf(parentOf(x));
//                1 .S为红色,S染黑,P染红,右旋P
                if (colorOf(sib) == RED) {
                    setColor(sib, BLACK);
                    setColor(parentOf(x), RED);
                    rotateRight(parentOf(x));
                    sib = leftOf(parentOf(x));// RN成为新的左节点
                }
//                2 .S为黑色,LN,RN也为 黑色 : S染红,X回溯至  P
                if (colorOf(rightOf(sib)) == BLACK &&
                        colorOf(leftOf(sib)) == BLACK) {
                    setColor(sib, RED);
                    x = parentOf(x);
                } else {
//                3 .S为黑色,黑LN : RN染黑,S染红,左旋S
                    if (colorOf(leftOf(sib)) == BLACK) {
                        setColor(rightOf(sib), BLACK);
                        setColor(sib, RED);
                        rotateLeft(sib);
                        sib = leftOf(parentOf(x));
                    }
//                4 .S为黑色,任意颜色RN,红色的LN:S变为P的颜色,P和S染黑,右旋P
                    setColor(sib, colorOf(parentOf(x)));
                    setColor(parentOf(x), BLACK);
                    setColor(leftOf(sib), BLACK);
                    rotateRight(parentOf(x));
                    x = root;
                }
            }
        }

        setColor(x, BLACK);
    }

    private static final long serialVersionUID = 919286545866124006L;

    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
//ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
// 可以使用 ObjectInputStream 读取(重构)对象。
// 通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
        // 将当前类的非静态和非瞬态字段写入此流。
        s.defaultWriteObject();


        s.writeInt(size);


        for (Iterator<Map.Entry<K,V>> i = entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<K,V> e = i.next();
            s.writeObject(e.getKey());
            s.writeObject(e.getValue());
        }
    }


    private void readObject(final java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        // Read in the Comparator and any hidden stuff
        s.defaultReadObject();

        // Read in size
        int size = s.readInt();

        buildFromSorted(size, null, s, null);
    }


    void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
            throws java.io.IOException, ClassNotFoundException {
        buildFromSorted(size, null, s, defaultVal);
    }


    void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
        try {
            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
        } catch (java.io.IOException cannotHappen) {
        } catch (ClassNotFoundException cannotHappen) {
        }
    }



    private void buildFromSorted(int size, Iterator<?> it,
                                 java.io.ObjectInputStream str,
                                 V defaultVal)
            throws  java.io.IOException, ClassNotFoundException {
        this.size = size;
        root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
                it, str, defaultVal);
    }


    @SuppressWarnings("unchecked")
    private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
                                                               int redLevel,
                                                               Iterator<?> it,
                                                               java.io.ObjectInputStream str,
                                                               V defaultVal)
            throws  java.io.IOException, ClassNotFoundException {


        if (hi < lo) return null;

        int mid = (lo + hi) >>> 1; //表示逻辑移,//表算术右移

        Entry<K,V> left  = null;
        if (lo < mid)
            left = buildFromSorted(level+1, lo, mid - 1, redLevel,
                    it, str, defaultVal);


        K key;
        V value;
        if (it != null) {
            if (defaultVal==null) {
                Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next();
                key = (K)entry.getKey();
                value = (V)entry.getValue();
            } else {
                key = (K)it.next();
                value = defaultVal;
            }
        } else { // use stream
            key = (K) str.readObject();
            value = (defaultVal != null ? defaultVal : (V) str.readObject());
        }

        Entry<K,V> middle =  new Entry<>(key, value, null);

        // color nodes in non-full bottommost level red
        if (level == redLevel)
            middle.color = RED;

        if (left != null) {
            middle.left = left;
            left.parent = middle;
        }

        if (mid < hi) {
            Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
                    it, str, defaultVal);
            middle.right = right;
            right.parent = middle;
        }

        return middle;
    }


    private static int computeRedLevel(int sz) {
        int level = 0;
        for (int m = sz - 1; m >= 0; m = m / 2 - 1)
            level++;
        return level;
    }


    static <K> Spliterator<K> keySpliteratorFor(NavigableMap<K,?> m) {
        if (m instanceof TreeMap) {
            @SuppressWarnings("unchecked") TreeMap<K,Object> t =
                    (TreeMap<K,Object>) m;
            return t.keySpliterator();
        }
        if (m instanceof TreeMap.DescendingSubMap) {
            @SuppressWarnings("unchecked") DescendingSubMap<K,?> dm =
                    (DescendingSubMap<K,?>) m;
            TreeMap<K,?> tm = dm.m;
            if (dm == tm.descendingMap) {
                @SuppressWarnings("unchecked") TreeMap<K,Object> t =
                        (TreeMap<K,Object>) tm;
                return t.descendingKeySpliterator();
            }
        }
        @SuppressWarnings("unchecked") NavigableSubMap<K,?> sm =
                (NavigableSubMap<K,?>) m;
        return sm.keySpliterator();
    }

    final Spliterator<K> keySpliterator() {
        return new KeySpliterator<K,V>(this, null, null, 0, -1, 0);
    }

    final Spliterator<K> descendingKeySpliterator() {
        return new DescendingKeySpliterator<K,V>(this, null, null, 0, -2, 0);
    }


    static class TreeMapSpliterator<K,V> {
        final TreeMap<K,V> tree;
        Entry<K,V> current; // traverser; initially first node in range
        Entry<K,V> fence;   // one past last, or null
        int side;                   // 0: top, -1: is a left split, +1: right
        int est;                    // size estimate (exact only for top-level)
        int expectedModCount;       // for CME checks

        TreeMapSpliterator(TreeMap<K,V> tree,
                           Entry<K,V> origin, Entry<K,V> fence,
                           int side, int est, int expectedModCount) {
            this.tree = tree;
            this.current = origin;
            this.fence = fence;
            this.side = side;
            this.est = est;
            this.expectedModCount = expectedModCount;
        }

        final int getEstimate() { // force initialization
            int s; TreeMap<K,V> t;
            if ((s = est) < 0) {
                if ((t = tree) != null) {
                    current = (s == -1) ? t.getFirstEntry() : t.getLastEntry();
                    s = est = t.size;
                    expectedModCount = t.modCount;
                }
                else
                    s = est = 0;
            }
            return s;
        }

        public final long estimateSize() {
            return (long)getEstimate();
        }
    }

    static final class KeySpliterator<K,V>
            extends TreeMapSpliterator<K,V>
            implements Spliterator<K> {
        KeySpliterator(TreeMap<K,V> tree,
                       Entry<K,V> origin, Entry<K,V> fence,
                       int side, int est, int expectedModCount) {
            super(tree, origin, fence, side, est, expectedModCount);
        }

        public KeySpliterator<K,V> trySplit() {
            if (est < 0)
                getEstimate(); // force initialization
            int d = side;
            Entry<K,V> e = current, f = fence,
                    s = ((e == null || e == f) ? null :      // empty
                            (d == 0)              ? tree.root : // was top
                                    (d >  0)              ? e.right :   // was right
                                            (d <  0 && f != null) ? f.left :    // was left
                                                    null);
            if (s != null && s != e && s != f &&
                    tree.compare(e.key, s.key) < 0) {        // e not already past s
                side = 1;
                return new KeySpliterator<>
                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super K> action) {
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            Entry<K,V> f = fence, e, p, pl;
            if ((e = current) != null && e != f) {
                current = f; // exhaust
                do {
                    action.accept(e.key);
                    if ((p = e.right) != null) {
                        while ((pl = p.left) != null)
                            p = pl;
                    }
                    else {
                        while ((p = e.parent) != null && e == p.right)
                            e = p;
                    }
                } while ((e = p) != null && e != f);
                if (tree.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }

        public boolean tryAdvance(Consumer<? super K> action) {
            Entry<K,V> e;
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            if ((e = current) == null || e == fence)
                return false;
            current = successor(e);
            action.accept(e.key);
            if (tree.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }

        public int characteristics() {
            return (side == 0 ? Spliterator.SIZED : 0) |
                    Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
        }

        public final Comparator<? super K>  getComparator() {
            return tree.comparator;
        }

    }

    static final class DescendingKeySpliterator<K,V>
            extends TreeMapSpliterator<K,V>
            implements Spliterator<K> {
        DescendingKeySpliterator(TreeMap<K,V> tree,
                                 Entry<K,V> origin, Entry<K,V> fence,
                                 int side, int est, int expectedModCount) {
            super(tree, origin, fence, side, est, expectedModCount);
        }

        public DescendingKeySpliterator<K,V> trySplit() {
            if (est < 0)
                getEstimate(); // force initialization
            int d = side;
            Entry<K,V> e = current, f = fence,
                    s = ((e == null || e == f) ? null :      // empty
                            (d == 0)              ? tree.root : // was top
                                    (d <  0)              ? e.left :    // was left
                                            (d >  0 && f != null) ? f.right :   // was right
                                                    null);
            if (s != null && s != e && s != f &&
                    tree.compare(e.key, s.key) > 0) {       // e not already past s
                side = 1;
                return new DescendingKeySpliterator<>
                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super K> action) {
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            Entry<K,V> f = fence, e, p, pr;
            if ((e = current) != null && e != f) {
                current = f; // exhaust
                do {
                    action.accept(e.key);
                    if ((p = e.left) != null) {
                        while ((pr = p.right) != null)
                            p = pr;
                    }
                    else {
                        while ((p = e.parent) != null && e == p.left)
                            e = p;
                    }
                } while ((e = p) != null && e != f);
                if (tree.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }

        public boolean tryAdvance(Consumer<? super K> action) {
            Entry<K,V> e;
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            if ((e = current) == null || e == fence)
                return false;
            current = predecessor(e);
            action.accept(e.key);
            if (tree.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }

        public int characteristics() {
            return (side == 0 ? Spliterator.SIZED : 0) |
                    Spliterator.DISTINCT | Spliterator.ORDERED;
        }
    }

    static final class ValueSpliterator<K,V>
            extends TreeMapSpliterator<K,V>
            implements Spliterator<V> {
        ValueSpliterator(TreeMap<K,V> tree,
                         Entry<K,V> origin, Entry<K,V> fence,
                         int side, int est, int expectedModCount) {
            super(tree, origin, fence, side, est, expectedModCount);
        }

        public ValueSpliterator<K,V> trySplit() {
            if (est < 0)
                getEstimate(); // force initialization
            int d = side;
            Entry<K,V> e = current, f = fence,
                    s = ((e == null || e == f) ? null :      // empty
                            (d == 0)              ? tree.root : // was top
                                    (d >  0)              ? e.right :   // was right
                                            (d <  0 && f != null) ? f.left :    // was left
                                                    null);
            if (s != null && s != e && s != f &&
                    tree.compare(e.key, s.key) < 0) {        // e not already past s
                side = 1;
                return new ValueSpliterator<>
                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super V> action) {
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            Entry<K,V> f = fence, e, p, pl;
            if ((e = current) != null && e != f) {
                current = f; // exhaust
                do {
                    action.accept(e.value);
                    if ((p = e.right) != null) {
                        while ((pl = p.left) != null)
                            p = pl;
                    }
                    else {
                        while ((p = e.parent) != null && e == p.right)
                            e = p;
                    }
                } while ((e = p) != null && e != f);
                if (tree.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }

        public boolean tryAdvance(Consumer<? super V> action) {
            Entry<K,V> e;
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            if ((e = current) == null || e == fence)
                return false;
            current = successor(e);
            action.accept(e.value);
            if (tree.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }

        public int characteristics() {
            return (side == 0 ? Spliterator.SIZED : 0) | Spliterator.ORDERED;
        }
    }

    static final class EntrySpliterator<K,V>
            extends TreeMapSpliterator<K,V>
            implements Spliterator<Map.Entry<K,V>> {
        EntrySpliterator(TreeMap<K,V> tree,
                         Entry<K,V> origin, Entry<K,V> fence,
                         int side, int est, int expectedModCount) {
            super(tree, origin, fence, side, est, expectedModCount);
        }

        public EntrySpliterator<K,V> trySplit() {
            if (est < 0)
                getEstimate(); // force initialization
            int d = side;
            Entry<K,V> e = current, f = fence,
                    s = ((e == null || e == f) ? null :      // empty
                            (d == 0)              ? tree.root : // was top
                                    (d >  0)              ? e.right :   // was right
                                            (d <  0 && f != null) ? f.left :    // was left
                                                    null);
            if (s != null && s != e && s != f &&
                    tree.compare(e.key, s.key) < 0) {        // e not already past s
                side = 1;
                return new EntrySpliterator<>
                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
            }
            return null;
        }

        public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            Entry<K,V> f = fence, e, p, pl;
            if ((e = current) != null && e != f) {
                current = f; // exhaust
                do {
                    action.accept(e);
                    if ((p = e.right) != null) {
                        while ((pl = p.left) != null)
                            p = pl;
                    }
                    else {
                        while ((p = e.parent) != null && e == p.right)
                            e = p;
                    }
                } while ((e = p) != null && e != f);
                if (tree.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }

        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
            Entry<K,V> e;
            if (action == null)
                throw new NullPointerException();
            if (est < 0)
                getEstimate(); // force initialization
            if ((e = current) == null || e == fence)
                return false;
            current = successor(e);
            action.accept(e);
            if (tree.modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return true;
        }

        public int characteristics() {
            return (side == 0 ? Spliterator.SIZED : 0) |
                    Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
        }

        @Override
        public Comparator<Map.Entry<K, V>> getComparator() {
            // Adapt or create a key-based comparator
            if (tree.comparator != null) {
                return Map.Entry.comparingByKey(tree.comparator);
            }
            else {
                return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> {
                    @SuppressWarnings("unchecked")
                    Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey();
                    return k1.compareTo(e2.getKey());
                };
            }
        }
    }
}

具体学习可参考 https://blog.csdn.net/Sun_TTTT/article/details/65445754

结论

1.红黑树不像AVL树一样,永远保持平衡

2.相对平衡

3.若H(Left)>=H(right) ,则H(left)<= 2*H(right)+1,但BH(left)===BH(right) 

4.定理N个节点的RBT,最大高度是2log(N+1)

查询效率 AVL 略好于 红黑树

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值