The red and black tree satisfies the nature:
* * node is not red or black.
* *. The root node is black.
All null junctions are called leaf nodes, and the color is considered black.
All red nodes have a black child node.
A. All paths from either node to its leaf node contain the same number of black nodes.
So all the nodes that the red and black tree inserted are red and then adjusted according to the rules.
When you delete it, you also need to replace the node with two children before and after, then delete it and adjust it.
/***************************************************************************** * Red-Black: * Or an empty tree, or a binary tree, meet the following properties * *. Nodes are not red or black. * *. The root node is black. All null junctions are called leaf nodes, and the color is considered black. All red nodes have a black child node. A. All paths from either node to its leaf node contain the same number of black nodes. * * Red black tree with good self-balance, performance better than BST, but less than AVL, in Linux for memory management * * So red and black in the insertion node is bound to be the red node, because the black node will destroy the nature of 5, but the following problems will occur ************************** /#ifndef redblack_h_#define Redblack_h_#include <iostream > #define BLACK 1#define RED 0using namespace std;/************** per-node information ***********************/class node{public:i NT value;/****** node stored value ******/bool color;/*** node colors ****/node *lefttree, *righttree, *parent;/******* left and right subtree, parent node ********* */Node (void): Color (RED), lefttree (null), Righttree (null), parent (null), value (0) {}/********** Gets the grandparent node ************/ node* grandparent (void) {return parent==null? null:parent->parent; }/*********** get tert-node ***********/node* uncle (void) {if (grandparent () = = NULL) {return NULL; } if (parent = = Grandparent ()->righttree) return grandparent ()->lefttree; else return grandparent ()->righttree; }/****** get sibling node *********/node* sibling (void) {return parent->lefttree==this?parent->righttree:parent-& Gt;lefttree; }};/****************** Red-Black class *********************/class redblacktree{private:void rotate_right (Node *p);/******* Right-handed * /void Rotate_left (node *p),/******* L-********/void Inorder (node *p),/******** first-order traversal ***********/string out Putcolor (bool color);/******** output Color **********/node* getsmallestchild (Node *p);/********** get the Kid Tree ***********/bool Del Ete_child (node *p, int data);/********* Delete subtree ************/void Delete_one_child (node *p);/********* Delete a child ************ /void Delete_case (node *p),/********* delete ************/void Insert (node *p, int data),/******** insert *********/void Insert_case (node *p);/******** insert case ***********/void DeleteTree (node *p);/******** Delete Tree */bool Find_data (node* p,int data)/********* find node ************/public:redblacktree (void);/******** Construction Interface * * * /~redblacktree ();/******** destroy interface ***********/void Inordertraverse ();/******** traversal interface ***********/void Insert ( int x);/******** Insert Interface ***********/BOOL Delete (int data),/******** delete interface ***********/bool find (int data);/******** Find interface * * * /private:node *root, *nil;};/ /*******************************************************************//method:rotate_right//FullName: redblacktree::rotate_right//access:private//returns:void//Qualifier: Right rotation//Parameter:node * p//**************** gp********************gp************** /**\******************/**\***********************//****************fa****x****** p****x**********************//***************/**\****--->***********/*\************************** p*****u*****************l**fa*************************//************/*\************************y**\************************//*********** l***y***************************u***********************//**************************************************** void Redblacktree::rotate_right (node *p) {Node *GP = p->grandparent (); Node *FA = p->parent; Node *y = p->righttree; Fa->lefttree = y; if (Y! = NIL) y->parent = FA; P->righttree = FA; Fa->parent = p; if (root = = FA) root = p; P->parent = GP; if (gp = NULL)/****** interpret the parent node's relationship with the grandparent node, thus repairing the relationship ********/{if (Gp->lefttree = = FA) Gp->lefttree = p; else Gp->righttree = p; }}//*******************************************************************//method:rotate_left//FullName: redblacktree::rotate_left//access:private//returns:void//Qualifier: L//Parameter:node * p//****************** *************************************************//*gp******************** gp************************//******************/**\******************/**\***********************//************** **fa****x****************p****x**********************//***************/**\****--->***********/*\*********** x****p*****************fa**r*************************//******************/*\*** /**\***************************//*****************y***r*************x****y************************ **//*******************************************************************void RedBlackTree::rotate_left (Node *p) { if (p->parent = = NULL) {root = P; Return } Node *GP = P->grandparent (); Node *FA = p->parent; Node *y = p->lefttree; Fa->righttree = y; if (Y! = NIL) y->parent = FA; P->lefttree = FA; Fa->parent = p; if (root = = FA) root = p; P->parent = GP;if (gp = NULL)/****** interpret the parent node's relationship with the grandparent node, thus repairing the relationship ********/{if (Gp->lefttree = = FA) Gp->lefttree = p; else Gp->righttree = p; }}//************************************//method:inorder//fullname:redblacktree::inorder//access:private//Re turns:void//Qualifier: Middle Sequence traversal node//Parameter:node * p//************************************void Redblacktree::inorder ( Node *p) {if (p = = NIL) return; if (p->lefttree) inorder (P->lefttree); cout << p->value << ""; if (p->righttree) inorder (p->righttree);} method:outputcolor//fullname:redblacktree::outputcolor//Access:privat e//returns:std::string//Qualifier: Output color//Parameter:bool color//************************************string Redblacktree::outputcolor (bool color) {return color? "BLACK": "RED";} method:getsmallestchild//FullName: redblacktree::getsmallestchild//access:private//returns:node*//Qualifier: Get the youngest child//Parameter:node * p//******* node* redblacktree::getsmallestchild (node* p) {if (P->lefttree = = NIL) return p; Return Getsmallestchild (P->lefttree);} method:delete_child//fullname:redblacktree::d elete_child//Access:priv ate//returns:bool//Qualifier: Delete child//Parameter:node * p//parameter:int data//************************************b Ool Redblacktree::d elete_child (Node *p, int data) {if (P->value > Data)/***** on the left *******/{if (p->le Fttree = = NIL)/***** no element found *******/{return false; } return Delete_child (P->lefttree, data); } else if (P->value < data)/***** on the right *******/{if (P->righttree = = NIL) {return F Alse; } return Delete_child (P->righttree, data); } else if (p->valUE = = data)/***** Find *******/{if (P->righttree = = NIL) {/****** If the node right subtree is empty, so there is at most one child, otherwise you need to replace the node and then go to the single node delete * /Delete_one_child (P); return true; } Node *smallest = Getsmallestchild (p->righttree);/* Search for subsequent nodes, then swap, delete */swap (P->value, Smallest->valu e); Delete_one_child (smallest); return true; } return false;} method:delete_one_child//Fullname:redblacktree::d elete_one_child// access:private//returns:void//Qualifier: Delete up to one child node//Parameter:node * p//*********************************** *void redblacktree::d elete_one_child (node *p) {Node *child = P->lefttree = NIL? p->righttree:p->lefttree; if (p->parent = = NULL && P->lefttree = = Nil && P->righttree = nil) {/**** only root node *******/ p = NULL; root = P; Return } if (p->parent = = NULL)/**** root node ****/{delete p;Child->parent = null;/** Reset root node */root = child; Root->color = BLACK; Return } if (p->parent->lefttree = = p)/** Replace the node **/{p->parent->lefttree = child; } else {p->parent->righttree = child; } child->parent = p->parent; if (P->color = = Black) {/***** If the deleted node is a black node, you need to adjust the tree, if it is a red node, then the subtree does not conflict, then directly delete the ********/if (Child->color = = Red /**** Sub-tree is a red node, then directly returned to the black node, and the nature has not been destroyed ****/{child->color = black; } else/******* otherwise needs to adjust the nature of *******/delete_case (child); } delete p;} method:delete_case//fullname:redblacktree::d elete_case//Access:privat e//returns:void//Qualifier: Delete//Parameter:node * p//************************************void redblacktree::d elet E_case (node *p) {if (p->parent = = NULL)/*** is the root node, directly dyed black ***/{p->color = black; Return } if (P->sibling ()->cOlor = = red)/**** Case 1: If the sibling node is red, adjust the color after the rotation, and finally follow the 2,3,4 processing ****/{p->parent->color = red; P->sibling ()->color = BLACK; if (p = = p->parent->lefttree) rotate_left (p->sibling ()); Else Rotate_right (p->sibling ()); if (P->parent->color = = Black && p->sibling ()->color = = Black && p->sibling ()->lefttree->color = = Black && p->sibling ()->righttree->color = = Black) {/**** Case 2.1: The parent node is black, the sibling node is black, and the sibling has two black child nodes so that the red brother can be dyed, then the parent node ****/p->sibling ()->color = red; Delete_case (p->parent); } else if (P->parent->color = = RED && p->sibling ()->color = = BLACK && p->sib Ling ()->lefttree->color = = Black && p->sibling ()->righttree->color = = Black) {/**** Case 2.2: If the sibling node is red, and the sibling has two black child nodes, this can dye the red brother, then adjust the parent node ****/p->sibling ()->color = red; P->parent->color =BLACK; } else {if (p->sibling ()->color = = Black) {/**** Case 3.1: If the sibling node is black, and brother left child red, right child black, swap sibling node and left child color change Chengdi Fourth Case ****/if (p = = P->parent->lefttree && p->sibling ()->lefttree->color = = RED && p->sibling ()->righttree->color = = BLACK) {p->sibling () color = RED; P->sibling ()->lefttree->color = BLACK; Rotate_right (p->sibling ()->lefttree); } else if (p = = P->parent->righttree && p->sibling ()->lefttree->color = = BLACK && p->sibling ()->righttree->color = = red) {/**** Case 3.2: If brother node is black, and brother left child black, right child red * * **/p->sibling ()->color = RED; P->sibling ()->righttree->color = BLACK; Rotate_left (p->sibling ()->righttree); }}/**** Case 4: If the sibling node is black, and the sibling opposite node child is red * * * */p->sibling ()->color = p->parent->color; P->parent->color = BLACK; if (p = = p->parent->lefttree) {/**** Case 4.1: node is left dial hand tree, then brother right child is red ****/p->sibling ()->righttree-> ; color = BLACK; Rotate_left (P->sibling ()); } else {/**** Case 4.2: node is right subtree, then sibling left child is Red ****/p->sibling ()->lefttree->color = BLACK; Rotate_right (P->sibling ()); }}}//************************************//method:insert//fullname:redblacktree::insert//access:private// returns:void//Qualifier: Inserting data//Parameter:node * p//parameter:int data//************************************void R Edblacktree::insert (Node *p, int data) {if (p->value >= data)/** the insertion is smaller (with equal to) the left, otherwise go to the right **/{if ( P->lefttree! = NIL) Insert (p->lefttree, data); else {node *tmp = new Node (); Tmp->value = data; Tmp->lefttree = Tmp->righttree = NIL; Tmp->parent = p; P->lefttree = tmp; Insert_case (TMP); }} else {if (p->righttree! = NIL) Insert (p->righttree, data); else {node *tmp = new Node (); Tmp->value = data; Tmp->lefttree = Tmp->righttree = NIL; Tmp->parent = p; P->righttree = tmp; Insert_case (TMP); }}}//************************************//method:insert_case//fullname:redblacktree::insert_case//Access: private//returns:void//Qualifier: Insert case, a total of five cases//Parameter:node * p//************************************void RedBl Acktree::insert_case (Node *p) {if (p->parent = = NULL)/**** Case 1: Direct dye black *****/{root = p; P->color = BLACK; Return if (P->parent->color = = red) {if (p->uncle ()->color = = red) {/* Case 3: Parent node and tertiary node are all red, will grandfather, father, uncle Full Color change, last recursive processing of grandfather nodes*/P->parent->color = p->uncle ()->color = BLACK; P->grandparent ()->color = RED; Insert_case (P->grandparent ()); else/* parent node and tertiary node are red, Uncle node Black */{if (P->parent->righttree = = P && p->grandparent () ->lefttree = = p->parent) {/** case 4:p is the right child of the parent node, the parent node is the left child of the grandparent node, this situation first adjusts the parent node so that it and both grandfather and father are on a line, note that after this rotation p **//******** The parent node of ********/Rotate_left (p); Rotate_right (P); P->color = BLACK; P->lefttree->color = P->righttree->color = RED; } else if (P->parent->lefttree = = P && p->grandparent ()->righttree = = p->parent) {/** case 5:p is the left child of the parent node, the parent node is the right child of the grandparent node **//******** This situation first adjusts the parent node so that it and both grandfather and father are on a line, notice that this rotates p into the new parent node ********/Rotate_ri Ght (P); Rotate_left (P); P->color = BLACK; P->lefttree->color = P->righttree->coloR = RED; } else if (P->parent->lefttree = = P && p->grandparent ()->lefttree = = p->parent) {/** Case 5.2:p is the right child of the parent node, the parent node is the left child of the grandparent node **/p->parent->color = BLACK; P->grandparent ()->color = RED; Rotate_right (p->parent); } else if (P->parent->righttree = = P && p->grandparent ()->righttree = = p->parent) {/** Case 4.2:p is the right child of the parent node, the parent node is the left child of the grandparent node **/p->parent->color = BLACK; P->grandparent ()->color = RED; Rotate_left (p->parent); }}}/******* finally considered case2: the situation, because the parent node is black, so you can exit the ********/}//************************************//directly Method:deletet ree//fullname:redblacktree::D eletetree//access:private//returns:void//Qualifier: Delete tree//Parameter:node * p//* void Redblacktree::D eletetree (Node *p) {if (!p | | p = NIL) { Return } deletetree (P->lefttree); DeleteTree (P->righttree); Delete p;} method:find_data//fullname:redblacktree::find_data//access:public//R eturns:bool//Qualifier: Lookup value//Parameter:int Data//************************************bool Redblacktree::find_data (node* p,int data) {if (p==null| | P==nil) return false;if (Data>p->value) return Find_data (p->righttree,data); else if (data<p->value) Return Find_data (P->lefttree,data); return true;} /************************************** Interface Section ********************************///********************************* method:redblacktree//fullname:redblacktree::redblacktree//access:public//returns://Qualifier: Initialize//Pa Rameter:void//************************************redblacktree::redblacktree (void) {NIL = new Node (); Nil->color = BLACK; root = NULL;} Redblacktree::~redblacktree (void) {if (root) deletetree (root); Delete NIL;} //****method:inorder//fullname:redblacktree::inorder//access:public//Returns: void//Qualifier: Traverse node//parameter:void//************************************void Redblacktree::inordertraverse ( void) {if (root = NULL) return; Inorder (root); cout << Endl;} method:insert//fullname:redblacktree::insert//access:public//Returns : void//Qualifier: Insert value//Parameter:int x//************************************void redblacktree::insert (int x) {if (Root = NULL) {root = new Node (); Root->color = BLACK; Root->lefttree = Root->righttree = NIL; Root->value = x; } else {Insert (root, x); }}//************************************//method:delete_value//fullname:redblacktree::d elete_value//Access:pu blic//returns:bool//Qualifier: Delete value//Parameter:int Data//************************************bool RedBlackTREE::D elete (int data) {return Delete_child (root, data);} method:find//fullname:redblacktree::find//access:public//Returns: bool//Qualifier: Lookup value//parameter:int data//************************************bool redblacktree::find (int data) { Return Find_data (Root,data);} #endif/*redblaock.h*/
Red and black Trees