Because we only see Section 13.3, we only implementRotateAndInsertFunction.
Thinking: if there is no parent node, when the parent node of z needs to be asked by the operator, we can use the lookup function to find the parent node and grandfather node of z from the root node to the path of the node z to be searched. Therefore, we can ask the parent node. This method adds the rotation function Time to O (lgn), and the insert function is also added to O (lgnlgn ). Saves space and adds execution time at the same time.
The detailed code is as follows:
# Include <iostream> using namespace std; # define BLACK 0 # define RED 1 # define Nil-1 # define LEN sizeof (struct Tree) struct Tree {struct Tree * left; struct Tree * right; int key; int color;}; struct Tree * root = NULL; struct Tree * nil = NULL; // binary search Tree lookup function of non-recursive version * ITERATIVE_TREE_SEARCH (struct Tree * x, int k, struct Tree * & p1, struct Tree * & p2) {// while (x! = Nil & k! = X-> key) {p1 = x; if (k <x-> key) {x = x-> left;} else x = x-> right; if (k! = X-> key) // if no value is found, the grandfather and parent node values are recorded. {P2 = p1; p1 = x;} return x;} void LEFT_ROTATE (struct Tree * T, struct Tree * x) {// left rotation: in three steps, ① ② describes the rotation code. Struct Tree * p1 = nil, * p2 = nil; struct Tree * y = x-> right; // Set the y node. X-> right = y-> left; // the code in this line and the following if structure indicate "y's left child becomes x's right child ". ① ITERATIVE_TREE_SEARCH (root, x-> key, p1, p2); if (p1 = nil) // the line of code and the following if-else structure expression process is "y becomes the new root of the subtree ". ② {Root = y;} else if (x = p1-> left) {p1-> left = y;} else p1-> right = y; y-> left = x; // This line of code and the following lines all express "x is the left child of y ". ③} Void RIGHT_ROTATE (struct Tree * T, struct Tree * x) {// Right rotate struct Tree * p1 = nil, * p2 = nil; struct Tree * y = x-> left; x-> left = y-> right; ITERATIVE_TREE_SEARCH (root, x-> key, p1, p2 ); if (p1 = nil) {root = y;} else if (x = p1-> right) {p1-> right = y ;} else p1-> left = y; y-> right = x;} void RB_INSERT_INSERT_FIXUP (struct Tree * T, struct Tree * z) {struct Tree * p1 = nil, * p2 = nil; ITERATIVE_TREE_SEARCH (root, z-> key, p1, p2); // p1 = z-> parent, p2 = z-> parent- > Parent while (1) {ITERATIVE_TREE_SEARCH (root, z-> key, p1, p2); // p1 is the parent node p2 is the grandfather node if (p1-> color! = RED) {break;} if (p1 = p2-> left) {struct Tree * y = p2-> right; // uncle node if (y-> color = RED) // Case 1: The uncle node is RED {// color p1, y, and p2 to maintain the property of 5. It also overcomes the problem that both the parent node of z and z are RED nodes. p1-> color = BLACK; y-> color = BLACK; p2-> color = RED; z = p2; // take z's grandfather node as the new node z into the next loop} else {if (z = p1-> right) // Scenario 2: check whether z is a right child and the primary node is black, provided that the p1 node is not a leaf node {// use a left-handed node to convert case 2 to case 3 z = p1; LEFT_ROTATE (T, z); // after entering the if statement, we can see that the rotating node cannot be a leaf node, so we don't have to infer whether z is a leaf node. ITERATIVE_TREE_SEARCH (root, z-> key, p1, p2); // p1 = z-> parent, p2 = z-> parent} p1-> color = BLACK; // Case 3: z is a left child and the uncle node is black. Change the color of the father and grandfather node of z and perform a right-hand operation to keep the character 5. P2-> color = RED; if (p2! = Nil) RIGHT_ROTATE (T, p2); // because p2 may be a leaf node, so use an if inference} else // The following else branches are similar to the above {struct Tree * y = p2-> left; if (y-> color = RED) {p1-> color = BLACK; y-> color = BLACK; p2-> color = RED; z = p2;} else {if (z = p1-> left) {z = p1; RIGHT_ROTATE (T, z); ITERATIVE_TREE_SEARCH (root, z-> key, p1, p2);} p1-> color = BLACK; p2-> color = RED; if (p2! = Nil) LEFT_ROTATE (T, p2) ;}} root-> color = BLACK; // Finally, BLACK is clicked on the root node .} Void RB_INSERT (struct Tree * T, struct Tree * z) {struct Tree * y = nil; struct Tree * x = root; while (x! = Nil) {y = x; if (z-> key <x-> key) {x = x-> left;} else x = x-> right ;} if (y = nil) {root = z;} else if (z-> key <y-> key) {y-> left = z ;} else y-> right = z; z-> left = nil; z-> right = nil; z-> color = RED; RB_INSERT_INSERT_FIXUP (T, z );} // traverse void InOderTraverse (struct Tree * p) {if (p! = Nil) {InOderTraverse (p-> left); cout <p-> key <"" <p-> color <"" <endl; inOderTraverse (p-> right) ;}} void main () {nil = new struct Tree [LEN]; nil-> key = Nil; nil-> color = BLACK; root = nil; int I = 0; struct Tree * ROOT = new struct Tree [LEN]; cin> ROOT-> key; RB_INSERT (nil, ROOT); root = ROOT; while (I! = 12) {struct Tree * z = new struct Tree [LEN]; cin> z-> key; RB_INSERT (root, z); I ++ ;} inOderTraverse (root );}
Zookeeper
Red/black tree implementation without parent node