从 二叉树  到 二叉搜索树(binary search tree)  到 平衡二叉树(AVL tree)  再到 红黑树( Red-Black tree)  最后实现 TreeMap 和 TreeSet
 
二叉树 与链表类似,二叉树的基本单元是节点,每个节点包含值、左子节点引用和右子节点引用,代表「父」与「子」之间的派生关系,体现了「一分为二」的分治逻辑
根节点 :位于二叉树顶层,没有父节点(节点 1) 
叶节点 :没有子节点的节点,其两个指针均指向 None(节点 8,9,10,11,12,13,14,15) 
边 :连接两个节点的线段,即节点引用(指针) 
节点所在的层 :从顶至底递增,根节点所在层为 1 (节点 4 在第 3 层) 
节点所在的度 :节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2(2) 
二叉树的高度 :从根节点到最远叶节点所经过的边的数量(高度为 3) 
节点的深度 :从根节点到该节点所经过的边的数量(节点 4 的深度为 2) 
节点的高度 :从距离该节点最远的叶节点到该节点所经过的边的数量(节点 4 的高度为 1) 
 
二叉搜索树 当一个二叉树满足以下条件,便可称为二叉搜索树:
左子树中所有节点的值 < 根节点的值 < 右子树中所有节点的值 
左右子树也满足条件 1 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 public  class  BinarySearchTree <T extends  Comparable <T>> {    private  Node<T> root;     public  BinarySearchTree ()  {         root = null ;     }     public  void  put (T data)  {         root = insert(root, data);     }     private  Node<T> insert (Node<T> root, T data)  {         if  (root == null ) {             return  new  Node <>(data);         }         if  (data.compareTo(root.data) < 0 ) {             root.left = insert(root.left, data);         } else  if  (data.compareTo(root.data) > 0 ) {             root.right = insert(root.right, data);         } else  {             System.out.println("已存在" );         }         return  root;     }     public  void  delete (T data)  {         root = delete(root, data);     }     private  Node<T> delete (Node<T> root, T data)  {         if  (root == null ) {             return  null ;         }         if  (data.compareTo(root.data) < 0 ) {             root.left = delete(root.left, data);         } else  if  (data.compareTo(root.data) > 0 ) {             root.right = delete(root.right, data);         } else  {             if  (root.left == null ) {                 return  root.right;             } else  if  (root.right == null ) {                 return  root.left;             } else  {                 Node<T> temp = findMin(root.right);                 root.data = temp.data;                 root.right = delete(root.right, temp.data);             }         }         return  root;     }     private  Node<T> findMin (Node<T> root)  {         while  (root.left != null ) {             root = root.left;         }         return  root;     }          static  class  Node <T> {         T data;         Node<T> left;         Node<T> right;         public  Node (T data)  {             this .data = data;         }         public  Node (T data, Node<T> left, Node<T> right)  {             this .data = data;             this .left = left;             this .right = right;         }     } } 
 
二叉搜索树对插入的顺序有要求 
二叉搜索树的查找、插入、删除的时间复杂度都是 O(logn) 
最为复杂的是删除操作,删除时为了保证 左子树中所有节点的值 < 根节点的值 < 右子树中所有节点的值,删除时会取删除节点的 右子树中最小叶节点,将删除节点的值替换为叶节点的值,并删除右子树中该叶节点(详见 delete 方法) 
 
DFS 与 BFS 关于二叉搜索树的遍历,存在两种遍历方式
深度优先搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 private  void  printDFS (Node<T> root)  {    List<List<Node<T>>> result = new  ArrayList <>();     dfs(root, 0 , result);     for  (List<Node<T>> list : result) {         for  (Node<T> node : list) {             System.out.print(node == null  ? "N "  : node.data + " " );         }         System.out.println();     } } private  void  dfs (Node<T> root, int  level, List<List<Node<T>>> result)  {    if  (level == result.size()) {         if  (root != null ) {             result.add(new  ArrayList <>(List.of(root)));         } else  {             return ;         }     } else  {         if  (root != null ) {             result.get(level).add(root);         } else  {             result.get(level).add(null );             return ;         }     }     dfs(root.left, level + 1 , result);     dfs(root.right, level + 1 , result); } 
 
广度优先搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private  void  printBFS (Node<T> root)  {    LinkedList<Node<T>> queue = new  LinkedList <>();     queue.add(root);     while  (!queue.isEmpty()) {         int  levelSize  =  queue.size();         for  (int  i  =  0 ; i < levelSize; i++) {             Node<T> node = queue.removeFirst();             if  (node != null ) {                 System.out.print(node.data + " " );             } else  {                 System.out.print("N " );                 continue ;             }             queue.add(node.left);             queue.add(node.right);         }         System.out.println();     } } 
 
平衡二叉树 由于二叉搜索树的结构与插入及删除有关,这样其结构就会出现不可控,可能会退化为链表,这样所有操作的时间复杂度将变为 O(n)
因此,一个能在插入和删除时自动平衡树结构的平衡二叉树应运而生
节点高度 平衡二叉树在二叉树的基础上增加了一个属性——高度
高度用来表示该节点处于平衡二叉树的层级,叶子节点的高度为 1,每距离叶子节点一个单位则高度 +1,如果左右子树的高度不一致,则取最高子树的高度
上图中,两个叶子节点 0003 和 0006 层高为 1,0005 层高为 2,根节点 0004 取较高的右子树高度 3
平衡因子 平衡因子是决定平衡二叉树是否启动自平衡的关键,通常 -1 ≤ 平衡因子 ≤ 1 时不需要调整,否则进行自平衡
某节点的平衡因子 = 该节点左子树高度 - 该节点右子树高度
如上图,
0004 节点的平衡因子 = 1 - 2 = -1
0005 节点的平衡因子 = 0 - 1 = -1
右旋 将节点 0003,0002,0001 依次插入平衡二叉树中
此时节点 0003 的平衡因子为 2,说明其左子树存在失衡
为保持平衡,需要将节点 0003 和 0002 进行 右旋 
左旋 将节点 0001,0002,0003 依次插入平衡二叉树中
此时节点 0001 的平衡因子为 -2,说明其右子树存在失衡
为保持平衡,需要将节点 0001 和 0002 进行 左旋 
右旋+左旋 将节点 0001,0003,0002 依次插入平衡二叉树中
此时节点 0001 的平衡因子为 -2,说明其右子树存在失衡
但 0002 < 0001 所以需要先将 0003 和 0002 进行右旋,然后再将 0001 和 0002 进行左旋
左旋 + 右旋 将节点 0003,0001,0002 依次插入平衡二叉树中
此时节点 0003 的平衡因子为 2,说明其左子树存在失衡
但 0002 > 0001 所以需要先将 0001 和 0002 进行左旋,然后再将 0003 和 0002 进行右旋
旋转的理解 
旋转是发生在两个节点间的操作 
右旋:将当前节点放到其左子节点的右子节点上 
左旋:将当前节点放到其右子节点的左子节点上 
旋转的选择:子节点 < 当前节点 => 右旋;当前节点 > 子节点 => 左旋 
 
实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 public  class  AVLTree <T extends  Comparable <T>> {    private  Node<T> root;     public  AVLTree ()  {         root = null ;     }     public  void  put (T data)  {         root = insert(root, data);     }     private  Node<T> insert (Node<T> node, T data)  {         if  (node == null ) {             return  new  Node <>(data);         }         if  (data.compareTo(node.data) < 0 ) {             node.left = insert(node.left, data);         } else  if  (data.compareTo(node.data) > 0 ) {             node.right = insert(node.right, data);         } else  {             return  node;         }         node.height = 1  + Math.max(getHeight(node.left), getHeight(node.right));         int  balance  =  getBalance(node);                                             if  (balance > 1  && data.compareTo(node.left.data) < 0 ) {                                                    return  rightRotate(node);         }                                             if  (balance < -1  && data.compareTo(node.right.data) > 0 ) {                                                    return  leftRotate(node);         }                                             if  (balance > 1  && data.compareTo(node.left.data) > 0 ) {                                                                 node.left = leftRotate(node.left);                                                    return  rightRotate(node);         }                                             if  (balance < -1  && data.compareTo(node.right.data) < 0 ) {                                                                 node.right = rightRotate(node.right);                                                    return  leftRotate(node);         }         return  node;     }          private  Node<T> rightRotate (Node<T> node)  {         Node<T> l = node.left;         Node<T> lr = l.right;         l.right = node;         node.left = lr;         node.height = 1  + Math.max(getHeight(node.left), getHeight(node.right));         l.height = 1  + Math.max(getHeight(l.left), getHeight(l.right));         return  l;     }          private  Node<T> leftRotate (Node<T> node)  {         Node<T> r = node.right;         Node<T> rl = r.left;         r.left = node;         node.right = rl;         node.height = 1  + Math.max(getHeight(node.left), getHeight(node.right));         r.height = 1  + Math.max(getHeight(r.left), getHeight(r.right));         return  r;     }     private  int  getHeight (Node<T> node)  {         if  (node == null ) {             return  0 ;         }         return  node.height;     }     private  int  getBalance (Node<T> node)  {         if  (node == null ) {             return  0 ;         }         return  getHeight(node.left) - getHeight(node.right);     }     public  void  print ()  {         printBFS(root);     }     private  void  printBFS (Node<T> node)  {         if  (node == null ) {             return ;         }         Queue<Node<T>> queue = new  LinkedList <>();         queue.add(root);         while  (!queue.isEmpty()) {             int  level  =  queue.size();             for  (int  i  =  0 ; i < level; i++) {                 Node<T> tNode = queue.poll();                 if  (tNode != null ) {                     System.out.print(tNode.data + " " );                 } else  {                     System.out.print("N " );                     continue ;                 }                 queue.add(tNode.left);                 queue.add(tNode.right);             }             System.out.println();         }     }     private  void  printDFS (Node<T> node)  {         if  (node == null ) {             return ;         }         List<List<Node<T>>> result = new  ArrayList <>();         dfs(node, 0 , result);     }     private  void  dfs (Node<T> node, int  level, List<List<Node<T>>> result)  {         if  (level == result.size()) {             if  (node != null ) {                 result.add(new  ArrayList <>(List.of(node)));             } else  {                 return ;             }         } else  {             if  (node != null ) {                 result.get(level).add(node);             } else  {                 result.get(level).add(null );                 return ;             }         }         dfs(node.left, level + 1 , result);         dfs(node.right, level + 1 , result);     }     public  void  delete (T data)  {         root = delete(root, data);     }     private  Node<T> delete (Node<T> node, T data)  {         if  (node == null ) {             return  null ;         }         if  (data.compareTo(node.data) < 0 ) {             node.left = delete(node.left, data);         } else  if  (data.compareTo(node.data) > 0 ) {             node.right = delete(node.right, data);         } else  {             if  (node.left == null  || node.right == null ) {                 node = node.left != null  ? node.left : node.right;             } else  {                 Node<T> temp = minValueNode(node.right);                 node.data = temp.data;                 node.right = delete(node.right, temp.data);             }         }         if  (node == null ) {             return  node;         }         node.height = 1  + Math.max(getHeight(node.left), getHeight(node.right));         int  balance  =  getBalance(node);         if  (balance > 1  && getBalance(node.left) >= 0 ) {             return  rightRotate(node);         }         if  (balance > 1  && getBalance(node.left) < 0 ) {             node.left = leftRotate(node.left);             return  rightRotate(node);         }         if  (balance < -1  && getBalance(node.right) <= 0 ) {             return  leftRotate(node);         }         if  (balance < -1  && getBalance(node.right) > 0 ) {             node.right = rightRotate(node.right);             return  leftRotate(node);         }         return  node;     }     private  Node<T> minValueNode (Node<T> node)  {         if  (node == null ) {             return  null ;         }         if  (node.left == null ) {             return  node;         }         return  minValueNode(node.left);     }     public  static  void  main (String[] args)  {         AVLTree<Integer> avlTree = new  AVLTree <>();         avlTree.put(5 );         avlTree.print();         avlTree.put(3 );         avlTree.print();         avlTree.put(4 );         avlTree.print();     }     static  class  Node <T> {         T data;         Node<T> left;         Node<T> right;         int  height;         public  Node (T data)  {             this .data = data;             this .height = 1 ;         }     } } 
 
红黑树 平衡二叉树为保证树的平衡,在插入和删除的时候可能会触发 logN 次旋转,随着 N 的不断增大,旋转的次数会不断增多。那么有没有一种能减少旋转次数的结构呢?答案就是——红黑树
约束 红黑树对每个节点增加了一个节点颜色的属性
旋转 红黑树的特点就是减少了旋转的次数,通过父节点与祖父节点的位置,以及父节点与叔节点的颜色来判断是否需要旋转
父节点位于祖父节点的右边,且父节点是红色,叔节点是黑色,新增节点为右子节点 
上图中:祖父节点为 0001,父节点为 0002,叔节点为 NULL,新增节点为 0003
这种情况下,只需将 0001 左旋  至 0002 的左子节点,并将 父节点置黑,祖父节点置红 
 
父节点位于祖父节点的右边,且父节点是红色,叔节点是黑色,新增节点为左子节点 
上图中:祖父节点为 0001,父节点为 0003,叔节点为 NULL,新增节点为 0002
这种情况下,需要先将 0003 右旋  到 0002 的右子节点,然后将 0001 左旋  到 0002 的左子节点,最后将 新增节点置黑,祖父节点置红 
 
父节点位于祖父节点的右边,且父节点和叔节点都是红色 
上图中:祖父节点为 0002,父节点为 0003,叔节点为 0001,新增节点为 0004
这种情况下,无论新增节点是在左子树上还是右子树上,都 不需要旋转调整结构,只需要改变颜色 ,将父节点与叔节点置为黑色,祖父节点置为红色,此处祖父节点为根节点,所以还需重置为黑色
 
父节点位于祖父节点的左边,且父节点是红色,叔节点是黑色,新增节点为左子节点 
上图中:祖父节点为 0003,父节点为 0002,叔节点为 NULL,新增节点为 0001
这种情况下,只需将 0003 右旋  至 0002 的右子节点,并将 父节点置黑,祖父节点置红 
 
父节点位于祖父节点的左边,且父节点是红色,叔节点是黑色,新增节点为右子节点 
上图中:祖父节点为 0003,父节点为 0001,叔节点为 NULL,新增节点为 0002
这种情况下,需要先将 0001 左旋  到 0002 的左子节点,然后将 0003 右旋  到 0002 的右子节点,最后将 新增节点置黑,祖父节点置红 
 
父节点位于祖父节点的左边,且父节点和叔节点都是红色 
上图中:祖父节点为 0003,父节点为 0002,叔节点为 0004,新增节点为 0001
与父节点位于祖父节点的右边,且父节点和叔节点都是红色的情况一致,都 不需要旋转调整结构,只需要改变颜色 
 
 
对比 AVL-Trees 将 0001~0010 分别插入平衡二叉树与红黑树中
红黑树舍弃了平衡二叉树严格要求的左右子树高度差,取而代之的是节点颜色
从而牺牲部分的查找性能来换取插入和删除的性能
实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 public  class  RBTee <T extends  Comparable <T>> {    private  static  final  boolean  RED  =  true ;     private  static  final  boolean  BLACK  =  false ;     private  Node<T> root;     public  RBTee ()  {         this .root = null ;     }     public  void  put (T value)  {         Node<T> newNode = new  Node <>(value);         insert(newNode);     }     private  void  insert (Node<T> newNode)  {                  Node<T> current = root;         Node<T> parent = null ;         while  (current != null ) {             parent = current;             if  (newNode.data.compareTo(current.data) < 0 ) {                 current = current.left;             } else  {                 current = current.right;             }         }                  newNode.parent = parent;         if  (parent == null ) {             root = newNode;         } else  if  (newNode.data.compareTo(parent.data) < 0 ) {             parent.left = newNode;         } else  {             parent.right = newNode;         }                  fixAfterInsertion(newNode);     }     private  void  fixAfterInsertion (Node<T> newNode)  {                  while  (newNode != root && newNode.parent.color == RED) {             Node<T> parent = newNode.parent;                          Node<T> grandParent = parent.parent;                          if  (parent == grandParent.left) {                                  Node<T> uncle = grandParent.right;                 if  (uncle != null  && uncle.color == RED) {                                          parent.color = BLACK;                     uncle.color = BLACK;                     grandParent.color = RED;                     newNode = grandParent;                 } else  {                                          if  (newNode == parent.right) {                         leftRotate(parent);                         newNode = parent;                         parent = newNode.parent;                     }                                          rightRotate(grandParent);                     parent.color = BLACK;                     grandParent.color = RED;                     newNode = parent;                 }             } else  {                 Node<T> uncle = grandParent.left;                 if  (uncle != null  && uncle.color == RED) {                                          parent.color = BLACK;                     uncle.color = BLACK;                     grandParent.color = RED;                     newNode = grandParent;                 } else  {                                          if  (newNode == parent.left) {                         rightRotate(parent);                         newNode = parent;                         parent = newNode.parent;                     }                                          leftRotate(grandParent);                     parent.color = BLACK;                     grandParent.color = RED;                     newNode = parent;                 }             }         }         root.color = BLACK;     }     private  void  leftRotate (Node<T> node)  {         Node<T> rightSon = node.right;         Node<T> leftGrandson = rightSon.left;         rightSon.left = node;         node.right = leftGrandson;         if  (leftGrandson != null ) {                          rightSon.left.parent = node;         }         rightSon.parent = node.parent;         if  (node.parent == null ) {             root = rightSon;         } else  if  (node == node.parent.left) {             node.parent.left = rightSon;         } else  {             node.parent.right = rightSon;         }         node.parent = rightSon;     }     private  void  rightRotate (Node<T> node)  {         Node<T> leftSon = node.left;         Node<T> rightGrandson = leftSon.right;         leftSon.right = node;         node.left = rightGrandson;         if  (rightGrandson != null ) {             leftSon.right.parent = node;         }         leftSon.parent = node.parent;         if  (node.parent == null ) {             root = leftSon;         } else  if  (node == node.parent.right) {             node.parent.right = leftSon;         } else  {             node.parent.left = leftSon;         }         node.parent = leftSon;     }     public  void  delete (T value)  {         Node<T> node = find(value);         if  (node == null ) {             return ;         }         delete(node);     }     private  void  delete (Node<T> node)  {         Node<T> son, parent;         boolean  color;         if  (node.left != null  && node.right != null ) {                          node = minValueNode(node.right);         }         if  (node.left != null ) {             son = node.left;         } else  {             son = node.right;         }         parent = node.parent;         color = node.color;         if  (son != null ) {             son.parent = parent;         }         if  (parent == null ) {             root = son;         } else  if  (node == parent.left) {             parent.left = son;         } else  {             parent.right = son;         }                  if  (color == BLACK) {             fixAfterDeletion(son, parent);         }     }     private  void  fixAfterDeletion (Node<T> node, Node<T> parent)  {                  Node<T> temp;                  while  (node != root && (node == null  || node.color == BLACK)) {                          if  (parent.left == node) {                                  temp = parent.right;                                  if  (temp.color == RED) {                     temp.color = BLACK;                     parent.color = RED;                     leftRotate(parent);                     temp = parent.right;                 }                 if  ((temp.left == null  || temp.left.color == BLACK) &&                         (temp.right == null  || temp.right.color == BLACK)) {                     temp.color = RED;                     node = parent;                     parent = node.parent;                 } else  {                     if  (temp.right == null  || temp.right.color == BLACK) {                         temp.left.color = BLACK;                         temp.color = RED;                         rightRotate(temp);                         temp = parent.right;                     }                     temp.color = parent.color;                     parent.color = BLACK;                     temp.right.color = BLACK;                     leftRotate(parent);                     node = root;                 }             } else  {                 temp = parent.left;             }         }     }     private  Node<T> minValueNode (Node<T> node)  {         if  (node.left == null ) {             return  node;         }         return  minValueNode(node.left);     }     private  Node<T> find (T data)  {         Node<T> current = root;         while  (current != null ) {             if  (data.compareTo(current.data) == 0 ) {                 return  current;             } else  if  (data.compareTo(current.data) < 0 ) {                 current = current.left;             } else  {                 current = current.right;             }         }         return  null ;     }     static  class  Node <T> {         T data;         boolean  color;         Node<T> left;         Node<T> right;         Node<T> parent;         public  Node (T data)  {             this .data = data;             this .color = RED;             this .left = null ;             this .right = null ;             this .parent = null ;         }     } } 
 
TreeMap 与 HashMap 和 LinkedHashMap 相似的是,他们内部都会有一个实现了 Map.Entry  的 Entry,这个 Entry 是他们存储的基本单元
TreeMap 的特点是它底层基于红黑树来实现,所以可以做到 Entry 的有序性
put 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 )                 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 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 private  void  fixAfterInsertion (Entry<K,V> x)  {    x.color = RED;     while  (x != null  && x != root && x.parent.color == RED) {                  if  (parentOf(x) == leftOf(parentOf(parentOf(x)))) {                          Entry<K,V> y = rightOf(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 == rightOf(parentOf(x))) {                     x = parentOf(x);                     rotateLeft(x);                 }                                  setColor(parentOf(x), BLACK);                 setColor(parentOf(parentOf(x)), RED);                 rotateRight(parentOf(parentOf(x)));             }         } else  {             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; } private  static  <K,V> Entry<K,V> parentOf (Entry<K,V> p)  {    return  (p == null  ? null : p.parent); } private  static  <K,V> boolean  colorOf (Entry<K,V> p)  {    return  (p == null  ? BLACK : p.color); } 
 
remove 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 public  V remove (Object key)  {    Entry<K,V> p = getEntry(key);     if  (p == null )         return  null ;     V  oldValue  =  p.value;     deleteEntry(p);     return  oldValue; } private  void  deleteEntry (Entry<K,V> p)  {    modCount++;     size--;                    if  (p.left != null  && p.right != null ) {                  Entry<K,V> s = successor(p);         p.key = s.key;         p.value = s.value;         p = s;     }                Entry<K,V> replacement = (p.left != null  ? p.left : p.right);     if  (replacement != null ) {                           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.left = p.right = p.parent = null ;                  if  (p.color == BLACK)                          fixAfterDeletion(replacement);     } else  if  (p.parent == null ) {          root = null ;     } else  {          if  (p.color == BLACK)             fixAfterDeletion(p);         if  (p.parent != null ) {             if  (p == p.parent.left)                 p.parent.left = null ;             else  if  (p == p.parent.right)                 p.parent.right = null ;             p.parent = null ;         }     } } 
 
未完待续…