Learning algorithm or suggest a look at the algorithm introduction
Introduction to the third edition of the algorithm if you do not see the mathematical deduction only to see the pseudo-code difficulty or moderate
This series is just a process of documenting my learning experience and pseudo-code conversion code
In-depth learning is also recommended to look at Algorithmic book tutorials more systematically.
The 13th chapter of the introduction to algorithms in this paper red and black trees
The code is written by me
Reprint please indicate the source
The red and black tree is a two-tree with a color
Has the following 5-point performance
1 each node or red or black
2 root node Black
3 each leaf node (nil) is black
4 If a node is red, its two child nodes are black
5 The number of black nodes is the same for each node on the path of the node to the descendant node
Nil node shared version
Hide Nil Nodes
The structure of the red and black trees is similar to a two-fork tree
However, pointers and color records are added to the parent node of the node
Enum Color { red = 1, black};struct node { color color_; Std::shared_ptr<node> Left_; Std::shared_ptr<node> Right_; Std::shared_ptr<node> Parent_; int value_; Node () { Left_ = Right_ = Parent_ = nullptr; Value_ =-1; Color_ = black; }};
Also created with the leaf node nil
std::shared_ptr<node> Nil (new node);
The print function and the two fork tree change little
void Printree (std::shared_ptr<node> root) { if (root = nil) { return; } Std::cout << root->value_ << ""; if (Root->left_!=nil) printree (Root->left_); if (root->right_! = nil) printree (root->right_);}
Rotation operation
Rotation is the most basic operation to maintain balance let's start with the study here.
In the actual operation of the rotation
Pseudo code
is actually
Change the left subtree of Y to the right subtree of x
X change to Zuozi of y
The actual code is
void Rightrotate (std::shared_ptr<node>& root, std::shared_ptr<node> x) { std::shared_ptr< Node> y = x->left_; X->left_ = y->right_; if (y->right_! = nil) Y->right_->parent_ = x; Y->parent_ = x->parent_; if (X->parent_ = = nil) { root = y; } else if (X->parent_->left_ = = x) { X->parent_->left_ = y; } else { x->parent_->right_ = y; } Y->right_ = x; X->parent_ = y;}
Let's create a red-and-black tree to test the rotation operation (the color is focused on rotation only)
The entire code is as follows
RbShow.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <memory> #include <iostream>using namespace std;enum Color {red = 1,black}; struct Node {Color color_;std::shared_ptr<node> left_;std::shared_ptr<node> right_;std::shared_ptr< Node> parent_;int Value_;node () {Left_ = Right_ = Parent_ = Nullptr;value_ = -1;color_ = Black;}}; std::shared_ptr<node> Nil (new node);std::shared_ptr<node> createnode (color color, int i) {std::shared_ptr <node> p (new node);p->color_ = Color;p->left_ = Nil;p->right_ = Nil;p->parent_ = Nil;p->value_ = I;re Turn p;} void Rightrotate (std::shared_ptr<node>& root, std::shared_ptr<node> x) {std::shared_ptr<node> y = X->left_;x->left_ = y->right_;if (y->right_! = nil) Y->right_->parent_ = X;y->parent_ = X->par Ent_;if (X->parent_ = = nil) {root = y;} else if (X->parent_->left_ = = x) {X->parent_->left_ = y;} else {x->parent_->right_ = y;} Y->riGht_ = X;x->parent_ = y;} void Leftrotate (std::shared_ptr<node>& root, std::shared_ptr<node> x) {std::shared_ptr<node> y = X->right_;x->right_ = Y->left_;if (Y->left_! = nil) Y->left_->parent_ = X;y->parent_ = x-> Parent_;if (X->parent_ = = nil) {root = y;} else if (X->parent_->left_ = = x) {X->parent_->left_ = y;} else {x->parent_->right_ = y;} Y->left_ = X;x->parent_ = y;} void Printree (std::shared_ptr<node> root) {if (root = nil) {return;} Std::cout << root->value_ << ""; if (root->left_! = nil) printree (Root->left_); if (Root->right_!) = nil) printree (root->right_);} void TestLeftRotate1 () {std::shared_ptr<node> root = CreateNode (black, 1); Root->parent_ = Nil;std::shared_ptr <node> x = Root;root->right_ = CreateNode (red, 2); root->right_->parent_ = root; Printree (root); std::cout << Std::endl; Leftrotate (root, x); Printree (root); std::cout << Std::endl;} void TEstRightRotate1 () {std::shared_ptr<node> root = CreateNode (black, 2); Root->parent_ = nil;std::shared_ptr< node> x = root;std::shared_ptr<node> y = CreateNode (red, 1); Root->left_ = Y;y->parent_ = x; Printree (root); std::cout << Std::endl; Rightrotate (root, x); Printree (root); std::cout << Std::endl;} int main () {TestLeftRotate1 (); TestRightRotate1 (); return 0;}
Code Run effect
Since the left and right rotations are mirror mappings, this is just about the left rotation.
After left rotation
Another multi-node rotation.
RbShow.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <memory> #include <iostream>using namespace std;enum Color {red = 1,black}; struct Node {Color color_;std::shared_ptr<node> left_;std::shared_ptr<node> right_;std::shared_ptr< Node> parent_;int Value_;node () {Left_ = Right_ = Parent_ = Nullptr;value_ = -1;color_ = Black;}}; std::shared_ptr<node> Nil (new node);std::shared_ptr<node> createnode (color color, int i) {std::shared_ptr <node> p (new node);p->color_ = Color;p->left_ = Nil;p->right_ = Nil;p->parent_ = Nil;p->value_ = I;re Turn p;} void Rightrotate (std::shared_ptr<node>& root, std::shared_ptr<node> x) {std::shared_ptr<node> y = X->left_;x->left_ = y->right_;if (y->right_! = nil) Y->right_->parent_ = X;y->parent_ = X->par Ent_;if (X->parent_ = = nil) {root = y;} else if (X->parent_->left_ = = x) {X->parent_->left_ = y;} else {x->parent_->right_ = y;} Y->riGht_ = X;x->parent_ = y;} void Leftrotate (std::shared_ptr<node>& root, std::shared_ptr<node> x) {std::shared_ptr<node> y = X->right_;x->right_ = Y->left_;if (Y->left_! = nil) Y->left_->parent_ = X;y->parent_ = x-> Parent_;if (X->parent_ = = nil) {root = y;} else if (X->parent_->left_ = = x) {X->parent_->left_ = y;} else {x->parent_->right_ = y;} Y->left_ = X;x->parent_ = y;} void Printree (std::shared_ptr<node> root) {if (root = nil) {return;} Std::cout << root->value_ << ""; if (root->left_! = nil) printree (Root->left_); if (Root->right_!) = nil) printree (root->right_);} void TestLeftRotate2 () {//Test 1 3 2 4std::shared_ptr<node> root = CreateNode (black, 1); Root->parent_ = NIL;ROOT-&G T;right_ = CreateNode (red, 3); Root->right_->parent_ = root;std::shared_ptr<node> x = root->right_;std:: Shared_ptr<node> y = CreateNode (red, 2); X->left_ = Y;y->parent_ = X;std::shAred_ptr<node> z = CreateNode (red, 4); x->right_ = Z;z->parent_ = x; Printree (root); std::cout << Std::endl; Leftrotate (root, x); Printree (root); std::cout << Std::endl;} void TestRightRotate1 () {//Test 9 6 8 4 2 5std::shared_ptr<node> root = CreateNode (black, 9); Root->parent_ = Nil ;std::shared_ptr<node> a = root;std::shared_ptr<node> B = CreateNode (black, ten); a->right_ = b;b-> Parent_ = a;std::shared_ptr<node> c = CreateNode (black, 6); A->left_ = C;c->parent_ = a;std::shared_ptr< Node> d = CreateNode (black, 8); c->right_ = D;d->parent_ = c;std::shared_ptr<node> E = CreateNode (black, 4); C->left_ = E;e->parent_ = c;std::shared_ptr<node> F = CreateNode (black, 2); E->left_ = F;f->parent_ = E;s td::shared_ptr<node> g = CreateNode (black, 5); e->right_ = G;g->parent_ = e; Printree (root); std::cout << Std::endl; Rightrotate (Root, c); Printree (root); std::cout << Std::endl;} int main () {TestlEftRotate1 (); std::cout << Std::endl; TestRightRotate1 (); return 0;}
The right rotation diagram is described here
When node 6 is rotated right
Introduction to Algorithms red-black Tree Learning rotation (II.)