Because only section 13.3 is displayedRotateAndInsertFunction.
Thinking: if the parent node is not included, when you need to access the parent node of Z, we can use the lookup function to find the parent and grandfather nodes of Z from the root node to the path of the Z node to be searched. Therefore, we can access the parent node. However, this method increases the rotation function time to O (lgn), and the insert function to O (lgnlgn ). Saves space and increases the running time.
The 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; // non-recursive Binary Search Tree lookup function struct tree * 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 the value to be searched is not found, record its grandfather and parent node values. {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 IF structure below indicate that "the left child of Y becomes the right child of X ". ① 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 line 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. And solved the problem that the parent node of Z and Z are both 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 judge 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); // Since P2 may be a leaf node, so it is best to use an if to judge} else // The else branch below is 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