Principle and java Implementation of red/Black Tree insertion, principle of red/black tree java
The RED/BLACK tree is a binary balanced search tree. Each node has a storage location to indicate the color of the node, which can be RED or BLACK. The red/black tree has the following properties:
(1) Each node is red or black.
(2) The root node is black.
(3) If a node is red, both of its sons are black.
(4) For each node, all paths from the node to its child node contain the same number of black nodes
With the property of the red/black tree, all implementations based on the red/black tree can ensure that the operation runs at the logarithm level (except for range search. The additional time required is proportional to the number of keys returned ).
Java TreeMap is implemented through the red/black tree.
The operation of the red/black tree is easy to confuse if it is not drawn. The following figure shows how to insert the red/black tree.
After a red node is inserted into the red/black tree, there are six situations: N indicates the inserted node, P indicates the parent node, u indicates the uncle node, and G indicates the grandfather node, X indicates the current operation node.
The Code is as follows:
1 public class RedBlackBST <Key extends Comparable <Key>, Value> {2 private Node root; 3 private static final boolean RED = true; 4 private static final boolean BLACK = false; 5 private class Node {6 private Key key Key; // key 7 private Value val; // Value 8 private Node left, right, parent; // left and right subtree and parent Node 9 private boolean color; // color of the link to which the parent Node points 10 11 public Node (Key key, Value val, Node parent, boolean color) {1 2 this. key = key; 13 this. val = val; 14 this. color = color; 15} 16} 17 18 public Value get (Key key) {19 Node x = root; 20 while (x! = Null) {21 int cmp = key. compareTo (x. key); 22 if (cmp <0) x = x. left; 23 else if (cmp> 0) x = x. right; 24 else return x. val; 25} 26 return null; 27} 28 29 public void put (Key key, Value val) {30 if (root = null) {// if it is a root node, create the Node as BLACK 31 root = new Node (key, val, null, BLACK); 32 return; 33} 34 // find the proper insertion position 35 Node parent = null; 36 Node cur = root; 37 while (cur! = Null) {38 parent = cur; 39 if (key. compareTo (cur. key)> 0) cur = cur. right; 40 else cur = cur. left; 41} 42 Node n = new Node (key, val, parent, RED ); // The normal new node is red 43 // Insert the new node to the 44 if (key. compareTo (parent. key)> 0) parent. right = n; 45 else parent. left = n; 46 // after inserting a new node, adjust the color and attributes of some nodes in the tree to ensure that the features of the red and black trees are not damaged. 47 fixAfterInsertion (n ); 48} 49 private Node parentOf (Node x) {50 return (x = null? Null: x. parent); 51} 52 private boolean colorOf (Node x) {53 return (x = null? BLACK: x. color); 54} 55 private Node leftOf (Node x) {56 return (x = null? Null: x. left); 57} 58 private Node rightOf (Node x) {59 return (x = null? Null: x. right); 60} 61 private void setColor (Node x, boolean color) {62 if (x! = Null) 63 x. color = color; 64} 65 66 private void fixAfterInsertion (Node x) {67 while (x! = Null & colorOf (parentOf (x) = RED) {68 Node grandPa = parentOf (x); 69 Node parent = parentOf (x ); 70 if (parent = leftOf (grandPa) {// case 1 | case2 | case3 71 Node uncle = rightOf (grandPa); 72 if (colorOf (uncle) = RED) {// case1, uncle is red 73 setColor (parent, BLACK); // set the parent node to 74 setColor (uncle, BLACK ); // set the uncle node to black 75 setColor (grandPa, RED); // set the grandfather node to RED 76 x = grandPa; // because the grandfather node turns from black to RED, therefore, you need to re-adjust the parent section. Point and Its ancestor's red/black attribute 77} else {// case2 | case3, uncle is black 78 if (x = rightOf (parent) {// case2 79 x = parent; 80 rotateLeft (x); 81} 82 // case3 83 setColor (parent, BLACK); 84 setColor (grandPa, RED); 85 rotateRight (grandPa ); 86} 87 88} else {// case4 | case 5 | case6 89 Node uncle = leftOf (grandPa); 90 if (colorOf (uncle) = RED) {// case4 | case5 | case6 91 setColor (parent, BLACK); 92 setColor (uncle, BL ACK); 93 setColor (grandPa, RED); 94 x = grandPa; 95} else {// case5 | case6, uncle is black 96 if (x = leftOf (parent) {// case5 97 x = parent; 98 rotateRight (x); 99} 100 // case6101 setColor (parent, BLACK); 102 setColor (grandPa, RED); 103 rotateLeft (grandPa); 104} 105} 106} 107 private void rotateLeft (Node x) {109 if (x = null) return; 110 Node y = x. right; 111 x. right = y. left; 112 if (y. left! = Null) 113 y. left. parent = x; 114 y. left = x; 115 y. parent = x. parent; 116 if (x. parent = null) {117 root = y; 118} 119 else if (x. parent. left = x) {120 x. parent. left = y; 121} else {122 x. parent. right = y; 123} 124 x. parent = y; 125} 126 private void rotateRight (Node x) {127 if (x = null) return; 128 Node y = x. left; 129 x. left = y. right; 130 if (y. right! = Null) 131 y. right. parent = x; 132 y. right = x; 133 y. parent = x. parent; 134 if (x. parent = null) {135 root = y; 136} else if (x. parent. left = x) {137 x. parent. left = y; 138} else {139 x. parent. right = y; 140} 141 x. parent = y; 142} 143 144}
The above rotateLeft and rotateRight must be illustrated as follows: