Red-Black tree C + + code implementation, including testing

Source: Internet
Author: User

#ifndef Rb_tree_h
#define Rb_tree_h

const int BLACK =-1;
const int RED = 1;


static int number1 = 0; Used to count the number of occurrences of an insert.
static int number2 = 0;
static int number3 = 0;
static int number4 = 0;
static int number5 = 0;
static int number6 = 0;


struct rb_tree_node{

Public
Rb_tree_node (int a)
{
key = A;
color = BLACK;
p = 0;
left = 0;
right = 0;
}
~rb_tree_node ()
{
}
int key;
int color;
Rb_tree_node* p;
Rb_tree_node* left;
rb_tree_node* right;

};

Static Rb_tree_node NIL = {0};
#define PNIL (&nil)

struct Rb_tree
{
Rb_tree ()
{
Root->left = Pnil;
Root->right = Pnil;
Root->p = Pnil;
}
rb_tree_node* Root=pnil;

Insert Node Z
void Rb_tree_insert (rb_tree* root, rb_tree_node* z);
After inserting node Z, adjust the tree to re-satisfy the conditions of the red-black tree.
void Rb_tree_insert_fixup (Rb_tree*root, rb_tree_node* z);

Delete Node Z
void Rb_tree_delete (rb_tree* root, rb_tree_node* z);
After deleting node z, adjust the tree so that the tree satisfies the conditions of the red and black tree again.
void Rb_tree_delete_fixup (rb_tree* root, rb_tree_node*z);


The precursor of X, otherwise return nullptr
Rb_tree_node* rb_tree_predecessor (rb_tree* root, rb_tree_node* x);
x rear drive, otherwise return nullptr
Rb_tree_node* rb_tree_successor (rb_tree* root, rb_tree_node* x);


Minimum value in a tree rooted in X
rb_tree_node* rb_tree_minmum (rb_tree_node* x);
Maximum value in a tree rooted in X
rb_tree_node* rb_tree_maxmum (rb_tree_node* x);


Left rotation of the X-node
void Rb_left_rotate (rb_tree* root, rb_tree_node* x);
Right rotation of the X-node
void Rb_right_rotate (Rb_tree*root, rb_tree_node* x);


Replace tree with node U root with tree with node V as root
void Rb_transplant (rb_tree* root, rb_tree_node* u, rb_tree_node*v);
The search node value is a node that is values and returns, and the search does not return Pnil
Rb_tree_node* Rb_search (rb_tree* root, int value);
};


void Rb_tree::rb_tree_insert (rb_tree* root, rb_tree_node* z)
{
Z->left = Pnil; Sentinel is not an empty node, new out of the rb_tree_node of the left and right children for the empty node is not sentinel, so before inserting, the child is placed before the Sentinel
Z->right = Pnil;
rb_tree_node* x = rb_tree::root;
rb_tree_node* Y=pnil;
while (x! = Pnil)
{
y = x;
if (Z->key < X->key)
x = x->left;
Else
x = x->right;
}
Z->p = y;
if (y = = pnil) Root->root = Z;
else if (Z->key < y->key) Y->left = Z;
else y->right = Z;
Z->color = RED;
Rb_tree_insert_fixup (root, z);
}

void Rb_tree::rb_tree_insert_fixup (rb_tree* root, Rb_tree_node*z)
{
while (Z->p->color = = red&&z->p! = Pnil)
{
if (Z->p->p->left = = z->p)
{
Rb_tree_node* y = z->p->p->right;
if (Y->color = = RED)
{
number1++;
Z->p->color = BLACK;
Y->color = BLACK;
Z->p->p->color = RED;
z = z->p->p;
}
Else
{
number2++;
if (z = = z->p->right)
{
number3++;
z = z->p;
Rb_left_rotate (root, z);
}
Z->p->color = BLACK;
Z->p->p->color = RED;
Rb_right_rotate (Root, z->p->p);
}
}
Else
{
Rb_tree_node* y = z->p->p->left;
if (Y->color = = RED)
{
number4++;
Z->p->color = BLACK;
Y->color = BLACK;
Z->p->p->color = RED;
z = z->p->p;
}
Else
{
number5++;
if (z = = z->p->left)
{
number6++;
z = z->p;
Rb_right_rotate (root, z);
}
Z->p->color = BLACK;
Z->p->p->color = RED;
Rb_left_rotate (Root, z->p->p);
}
}
}
Root->root->color = BLACK;
}

void Rb_tree::rb_left_rotate (rb_tree* root, rb_tree_node* x)
{
Rb_tree_node* y = x->right;
X->right = y->left;
if (Y->left!=pnil)
Y->left->p = x;
Y->p = x->p;
if (x->p = = pnil) Root->root = y;
else if (x->p->left ==x) x->p->left = y;
else x->p->right = y;
X->p = y;
Y->left = x;
}

void Rb_tree::rb_right_rotate (Rb_tree*root, rb_tree_node* x)
{
Rb_tree_node* y = x->left;
X->left = y->right;
if (y->right! = Pnil)
Y->right->p = x;
Y->p = x->p;
if (x->p = = pnil) Root->root = y;
else if (X->p->left = = x) X->p->left = y;
else x->p->right = y;
X->p = y;
Y->right = x;
}

Rb_tree_node* rb_tree::rb_tree_predecessor (rb_tree* root, rb_tree_node* x)
{
if (x = = Rb_tree_minmum (root->root)) return x;
if (x->left! = Pnil) return rb_tree_maxmum (X->left);
Rb_tree_node* y = x->p;
while (Y! = Pnil&&x = = y->left)
{
x = y;
y = y->p;
}
return y;
}

Rb_tree_node* rb_tree::rb_tree_successor (rb_tree* root, rb_tree_node* x)
{
if (x = = Rb_tree_maxmum (root->root)) return x;
if (x->right! = Pnil) return rb_tree_minmum (x->right);
Rb_tree_node* y = x->p;
while (Y! = Pnil&&x = = y->right)
{
x = y;
y = y->p;
}
return y;
}

rb_tree_node* rb_tree::rb_tree_minmum (rb_tree_node* x)
{
while (x->left! = Pnil)
x = x->left;
return x;
}

rb_tree_node* rb_tree::rb_tree_maxmum (rb_tree_node* x)
{
while (x->right! = Pnil)
x = x->right;
return x;
}

void Rb_tree::rb_transplant (rb_tree* root, rb_tree_node* u, rb_tree_node* v)
{
if (u->p = = pnil) Root->root = v;
else if (U = = u->p->left) u->p->left=v;
else U->p->right = v;
if (V!=pnil)
V->p = u->p;
}

Rb_tree_node* Rb_tree::rb_search (rb_tree* root, int value)
{
rb_tree_node* temp = root->root;
while (temp! = pnil&&temp->key! = value)
{
if (Value < Temp->key)
{
temp = temp->left;
}
Else
{
temp = temp->right;
}
}
return temp;
}

void Rb_tree::rb_tree_delete (rb_tree* root, rb_tree_node* z)
{
Rb_tree_node* y = z;
rb_tree_node* x;
int origin_color = y->color;

if (Z->left = = Pnil)
{
x = z->right;
Rb_transplant (Root, z, z->right);
}
else if (z->right = = Pnil)
{
x = z->left;
Rb_transplant (Root, z, z->left);
}
Else
{
y = Rb_tree_minmum (z->right);
Origin_color = y->color;
x = y->right;
if (y->p = = Z)
{
X->p = y; To prevent Y's child nodes from being sentinels, you need to find the parent node of x when you delete the adjustment, and the Sentinel has no parent node.
}
Else
{
Rb_transplant (Root, y, y->right);
Y->right = z->right;
Y->right->p = y;
}
Rb_transplant (Root, z, y);
Y->left = z->left;
Y->left->p = y;
Y->color = z->color;

Z->p = nullptr; When node z is deleted, the parent node, child node pointer is empty, only the region of node Z is deleted
Z->right = nullptr;
Z->left = nullptr;
Delete Z;
}
if (Origin_color = = BLACK)
{
Rb_tree_delete_fixup (root, x);
}
}

void Rb_tree:: Rb_tree_delete_fixup (rb_tree* root, Rb_tree_node*z)
{
while (Z! = Root->root&&z->color = = BLACK)
{
if (z = = z->p->left)
{
Rb_tree_node* y = z->p->right;
if (Y->color = = RED)/////case1
{
Y->color = BLACK;
Z->p->color = RED;
Rb_left_rotate (Root, z->p);
y = z->p->right; Go to one of the case2,3,4
}
if (Y->left->color = = Black&&y->right->color = = BLACK)
{
Y->color = RED; Case2
z = z->p;
}
Else
{
if (Y->right->color = = BLACK)
{
Y->left->color = BLACK;
Y->color = RED;
Rb_right_rotate (root, y); Case3 go to Case4
y = z->p->right;
}
Y->color = z->p->color;
Z->p->color = BLACK; Case4;
Y->right->color = BLACK;
Rb_left_rotate (Root, z->p);
z = root->root;
}
}
Else////with the above left and right interchange
{
Rb_tree_node* y = z->p->left;
if (Y->color = = RED)
{
Y->color = BLACK;
Z->p->color = RED;
Rb_right_rotate (Root, z->p);
y = z->p->left;
}
if (Y->right->color = = Black&&y->left->color = = BLACK)
{
Y->color = RED;
z = z->p;
}
Else
{
if (Y->left->color = = BLACK)
{
Y->right->color = BLACK;
Y->color = RED;
Rb_left_rotate (root, y);
y = z->p->left;
}
Y->color = z->p->color;
Z->p->color = BLACK;
Y->left->color = BLACK;
Rb_right_rotate (Root, z->p);
z = root->root;
}
}
}
Z->color = BLACK;
}
#endif

#include "rb_tree.h"
#include <iostream>
using namespace Std;


void print (rb_tree* root)/////output all tree node values from small to large
{
rb_tree_node* pmin = Root->rb_tree_minmum (root-> root);
rb_tree_node* Pmax = Root->rb_tree_maxmum (root->root);
int i = 0;
while (true)
{
if (i++% = = 0) cout << Endl;
cout << pmin->key << "";
if (pmin = = Pmax) break;
Pmin = root->rb_tree_successor (root, Pmin);
}
}
int main ()
{
int a[1000];
for (int i = 0; i < i++)
{
A[i] = rand ()%;
}

rb_tree* root = new Rb_tree ();
for (int i = 0; i < i++)
{
rb_tree_node* z = new Rb_tree_node (A[i]);
Root->rb_tree_insert (ROOT,Z);
}
/////corresponds to the inserted case
cout << endl << number1<< "<<number2<<" <<number3 << "<<number4<<" <<number5<< "<<number6<< Endl;
cout << Endl << "====================" << Endl;
cout << root->root->key << << root->root->color << Endl;

cout << root->root->left->key << "<< root->root->left->color << Endl;
cout << root->root->right->key << "<< root->root->right->color << Endl;

cout << root->root->left->left->key << "<< root->root->left->left->color << Endl;
cout << root->root->left->right->key << "<< root->root->left->right-> Color << Endl;

cout << root->root->right->left->key << "<< root->root->right->left-> Color << Endl;
cout << root->root->right->right->key << "<< root->root->right->right-> Color << Endl;


cout << "++++++++++++++++++++++++++++++++++++++" << Endl;
rb_tree_node* pmin = Root->rb_tree_minmum (root->root);
rb_tree_node* Pmax = Root->rb_tree_maxmum (root->root);
print (root);
cout << Endl << endl << "++++++++++++++++++++++++++++++++" << Endl;
rb_tree_node* T = root->rb_search (root, 50);
if (t! = Pnil)
{
cout << t->key << Endl;
Root->rb_tree_delete (root, t);
print (root);
}
else cout << "not present" << Endl;

}

Bibliography: An Introduction to Algorithms

Red-Black tree C + + code implementation, including testing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.