#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;
enum _CORLOR{
BLACK = 0,
RED,
MAX_CORLOR
};
template<class elemType>
struct rbNode{
rbNode<elemType> *lLink;//left child node
rbNode<elemType> *rLink;//right child node
rbNode<elemType> *pLink;//point to parent node
elemType info;
int corlor;
};
rbNode<int> nil = {NULL, NULL, NULL, 0x7fffffff, BLACK};
template<class elemType>
rbNode<elemType>* findElem(rbNode<elemType> *root, elemType info)
{
rbNode<elemType> *pTmp = NULL;
if(root != NULL)
{
if(info == root->info)
{
return root;
}
if( root->info > info && root->lLink != &nil)
{
return findElem(root->lLink, info);
}
printf(" %d\n", root->info);
if(root->info < info && root->rLink != &nil)
{
return findElem(root->rLink, info);
}
}
return NULL;
}
template<class elemType>
rbNode<elemType>* successorElem(rbNode<elemType> *node)
{
rbNode<elemType> *pTmp = node;
rbNode<elemType> *pRes = &nil;
if(node == &nil)
{
printf("error: input node is nil\n");
return NULL;
}
if(pTmp != &nil && pTmp->rLink != &nil)
{
while(pTmp->lLink != &nil)
{
pTmp = pTmp->lLink;
}
pRes = pTmp->pLink;
return pRes;
}
while(pTmp != &nil && pTmp->pLink != &nil)
{
if(pTmp == pTmp->pLink->rLink)//
{
pTmp = pTmp->pLink;
}
else
{
pRes = pTmp;
break;
}
}
return pRes;
}
template<class elemType>
int left_rotate(rbNode<elemType> *root)
{
if(root == &nil)
{
printf("error:input root is NULL\n");
return 0;
}
if(root->rLink == &nil)
{
printf("error:right sub tree of root is NULL\n");
return 0;
}
rbNode<elemType> *pTmp = root->rLink;
root->rLink = pTmp->lLink;
if(root->rLink != &nil)
{
root->rLink->pLink = root;
}
pTmp->pLink = root->pLink;
if(pTmp->pLink->lLink == root)
{
pTmp->pLink->lLink = pTmp;
}
else
{
pTmp->pLink->rLink = pTmp;
}
root->pLink = pTmp;
root->pLink = pTmp;
pTmp->lLink = root;
return 0;
}
template<class elemType>
int right_rotate(rbNode<elemType> *root)
{
if(root == &nil)
{
printf("error:input root is NULL\n");
return 0;
}
if(root->lLink == &nil)
{
printf("error:right sub tree of root is NULL\n");
return 0;
}
rbNode<elemType> *pTmp = root->lLink;
root->lLink = pTmp->rLink;
if(root->lLink != &nil)
{
root->lLink->pLink = root;
}
pTmp->pLink = root->pLink;
if(pTmp->pLink->lLink == root)
{
pTmp->pLink->lLink = pTmp;
}
else
{
pTmp->pLink->rLink = pTmp;
}
root->pLink = pTmp;
pTmp->rLink = root;
return 0;
}
template<class elemType>
int rb_insert_fixup(rbNode<elemType> **root, rbNode<elemType> *newNode)
{
rbNode<elemType> *pTmpX = newNode;
while(pTmpX->pLink->corlor == RED)
{
//printf("%s(%d): cur node %d, parent node %d\n",
// __FILE__, __LINE__, pTmpX->info, pTmpX->pLink->info);
rbNode<elemType> *pTmpFather = pTmpX->pLink;
//if this is the left child of parent
if( pTmpFather->pLink != &nil && pTmpFather == pTmpFather->pLink->lLink)
{
printf("%s(%d): cur node %d, parent node %d, grand parent %d\n",
__FILE__, __LINE__, pTmpX->info, pTmpX->pLink->info,
pTmpFather->pLink->info);
rbNode<elemType> *pTmpUncle = pTmpFather->pLink->rLink;
if(pTmpUncle != &nil && pTmpUncle->corlor == RED)
{
printf("enter case 1\n");
pTmpUncle->corlor = BLACK;
pTmpFather->corlor = BLACK;
pTmpFather->pLink->corlor = RED;
pTmpX = pTmpFather->pLink;//the next process node
}
else
if(pTmpX == pTmpFather->rLink)
{
printf("enter case 2\n");
pTmpX= pTmpFather;//the next process node
rbNode<elemType> *pTmpY = pTmpX;
if(*root == pTmpY)
{
*root = pTmpY->rLink;
}
left_rotate(pTmpY);
}
//case 3
else
{
printf("enter case 3\n");
pTmpX->pLink->corlor = BLACK;
if(pTmpX->pLink->pLink != &nil)
{
pTmpX->pLink->pLink->corlor = RED;
if(*root == pTmpX->pLink->pLink)
{
*root = pTmpX->pLink;
}
right_rotate(pTmpX->pLink->pLink);
}
}
}
//if this is the right child of parent
else if(pTmpFather == pTmpFather->pLink->rLink)
{
rbNode<elemType> *pTmpUncle = pTmpFather->pLink->lLink;
if(pTmpUncle->corlor == RED)
{
printf("enter r case 1\n");
pTmpUncle->corlor = BLACK;
pTmpFather->corlor = BLACK;
pTmpFather->pLink->corlor = RED;
pTmpX = pTmpFather->pLink;//the next process node
}
else
if(pTmpX == pTmpFather->lLink)
{
printf("enter r case 2\n");
pTmpX= pTmpFather;//the next process node
rbNode<elemType> *pTmpY = pTmpX;
if(*root == pTmpY)
{
*root = pTmpY->lLink;
}
right_rotate(pTmpY);
}
//case 3
else
{
printf("enter r case 3\n");
pTmpX->pLink->corlor = BLACK;
if(pTmpX->pLink->pLink != &nil)
{
pTmpX->pLink->pLink->corlor = RED;
if(*root == pTmpX->pLink->pLink)
{
*root = pTmpX->pLink;
}
left_rotate(pTmpX->pLink->pLink);
}
}
}
(*root)->corlor = BLACK;
}
proc_over:
return 0;
}
template<class elemType>
int insertNode(rbNode<elemType> **root, rbNode<elemType> *newNode)
{
rbNode<elemType> *pTmpY = &nil;
rbNode<elemType> *pTmpX = *root;
while(pTmpX != &nil)
{
printf("%s(%d):pTmpX info %d\n", __FILE__, __LINE__, pTmpX->info);
pTmpY = pTmpX;
if( newNode->info == pTmpX->info)
{
printf("error:the same info %d in the tree\n", newNode->info);
break;
}
else
if( newNode->info > pTmpX->info)
{
pTmpX = pTmpX->rLink;
}
else
{
pTmpX = pTmpX->lLink;
}
}
//have the same node in the tree
if(pTmpX != &nil)
{
printf("error:the same info in the tree\n");
goto proc_over;
}
//tree has no entry yet.
if(pTmpY == &nil)
{
*root = newNode;
newNode->pLink = &nil;
}
else
{
if( newNode->info > pTmpY->info)
{
pTmpY->rLink = newNode;
}
else
{
pTmpY->lLink = newNode;
}
newNode->pLink = pTmpY;
}
newNode->lLink = &nil;
newNode->rLink = &nil;
newNode->corlor = RED;
printf("%s(%d):root %d\n", __FILE__, __LINE__, (*root)->info);
traverseTree(*root);
printf("%s(%d):\n", __FILE__, __LINE__);
rb_insert_fixup(root, newNode);
printf("%s(%d):\n", __FILE__, __LINE__);
proc_over:
return 0;
}
template<class elemType>
int rb_delete_fixup(rbNode<elemType> **root, rbNode<elemType> *delNode)
{
rbNode<elemType> *pTmpX = delNode;
while(pTmpX != *root && pTmpX->corlor == BLACK)
{
//cur node is the left child of parent
if(pTmpX == pTmpX->pLink->lLink)
{
//brother node
rbNode<elemType> *pTmpY = pTmpX->pLink->rLink;
if(pTmpY != &nil && pTmpY->corlor == RED)
{
printf("delete fixup left case 1\n");
//case 1
pTmpY->corlor = BLACK;
pTmpY->pLink->corlor = RED;
if(*root == pTmpY->pLink)
{
*root = pTmpY;
}
left_rotate(pTmpY->pLink);
pTmpY = pTmpX->pLink->rLink;
}
if(pTmpY != &nil && pTmpY->lLink->corlor == BLACK
&& pTmpY->rLink->corlor == BLACK)
{
printf("delete fixup left case 2\n");
//case 2
pTmpY->corlor = RED;
pTmpX = pTmpX->pLink;
}
else if(pTmpY->lLink != &nil && pTmpY->rLink->corlor == BLACK)
{
printf("delete fixup left case 3\n");
//case 3
pTmpY->lLink->corlor = BLACK;
pTmpY->corlor = RED;
right_rotate(pTmpY);
pTmpY = pTmpX->pLink->rLink;
}
else
{
printf("delete fixup left case 4\n");
//case 4
pTmpY->corlor = pTmpX->pLink->corlor;
pTmpX->pLink->corlor = BLACK;
pTmpY->rLink->corlor = BLACK;
if(pTmpX->pLink == *root)
{
*root = pTmpX;
}
left_rotate(pTmpX->pLink);
}
}
else//cur node is the right child of parent
{
//brother node
rbNode<elemType> *pTmpY = pTmpX->pLink->lLink;
if(pTmpY != &nil && pTmpY->corlor == RED)
{
printf("delete fixup right case 1\n");
//case 1
pTmpY->corlor = BLACK;
pTmpY->pLink->corlor = RED;
if(*root == pTmpY->pLink)
{
*root = pTmpY;
}
right_rotate(pTmpY->pLink);
pTmpY = pTmpX->pLink->lLink;
}
if(pTmpY != &nil && pTmpY->lLink->corlor == BLACK
&& pTmpY->rLink->corlor == BLACK)
{
printf("delete fixup right case 2\n");
//case 2
pTmpY->corlor = RED;
pTmpX = pTmpX->pLink;
}
else if(pTmpY->rLink != &nil && pTmpY->lLink->corlor == BLACK)
{
printf("delete fixup right case 3\n");
//case 3
pTmpY->rLink->corlor = BLACK;
pTmpY->corlor = RED;
left_rotate(pTmpY);
pTmpY = pTmpX->pLink->lLink;
}
else
{
printf("delete fixup right case 4\n");
//case 4
pTmpY->corlor = pTmpX->pLink->corlor;
pTmpX->pLink->corlor = BLACK;
pTmpY->lLink->corlor = BLACK;
if(pTmpX->pLink == *root)
{
*root = pTmpX;
}
right_rotate(pTmpX->pLink);
}
}
}
return 0;
}
template<class elemType>
int deleteNode(rbNode<elemType> **root, rbNode<elemType> *delNode)
{
rbNode<elemType> *pY = NULL;
rbNode<elemType> *pX = NULL;
if(delNode->lLink == &nil || delNode->rLink == &nil)
{
pY = delNode;
}
else
{
pY = successorElem(delNode);
}
if(pY->lLink != &nil)
{
pX = pY->lLink;
}
else
{
pX = pY->rLink;
}
pX->pLink = pY->pLink;
if(pY->pLink == &nil)
{
*root = pX;
}
else
{
if(pY = pY->pLink->lLink)
{
pY->pLink->lLink = pX;
}
else
{
pY->pLink->rLink = pX;
}
}
printf("%s(%d): %d, %d, %d\n", __FILE__, __LINE__,
delNode->info, pY->info, pX->info);
if(pY != delNode)
{
delNode->info = pY->info;
}
if(pY->corlor == BLACK)
{
printf("%s(%d):enter fixup pY %d\n", __FILE__, __LINE__, delNode->info);
rb_delete_fixup(root, pX);
}
printf("%s(%d): %d, %d\n", __FILE__, __LINE__, delNode->info, pX->info);
return 0;
}
template<class elemType>
int traverseTree(rbNode<elemType> *root)
{
if(root != &nil)
{
if(root->lLink != &nil)
{
traverseTree(root->lLink);
}
printf(" %d, parent %d, corlor %s\n",
root->info, root->pLink->info, root->corlor==0?"BLACK":"RED");
if(root->rLink != &nil)
{
traverseTree(root->rLink);
}
}
return 0;
}
int main()
{
vector<int> A;
A.resize(14);
rbNode<int> *tree = &nil;
A ={27, 17, 3, 16, 13, 10, 1, 5, 7, 12, 4, 8, 9, 0};
for(auto entry:A)
{
cout << entry<<endl;
}
printf("**************************\n");
for(auto entry:A)
{
rbNode<int> *newNode = new rbNode<int>;
newNode->info = entry;
newNode->lLink = &nil;
newNode->rLink = &nil;
newNode->pLink = &nil;
newNode->corlor = RED;
printf("begin**insert %d, root %d\n", newNode->info, tree->info);
insertNode(&tree, newNode );
printf("end**insert %d, root %d***********************\n", newNode->info, tree->info);
traverseTree(tree);
printf("**************************\n");
// if(newNode->info == 3)
// break;
}
traverseTree(tree);
printf("**************************\n");
rbNode<int> *delNode = NULL;
delNode = findElem(tree, 3);
if(delNode == NULL)
{
printf("do not find info %d\n", 3);
}
else
{
deleteNode(&tree, delNode);
}
printf("****** after delete 3, root %d********************\n", tree->info);
traverseTree(tree);
printf("**************************\n");
return 0;
}