#pragma once
#include <iostream>
const int RED = 0;
const int BLACK = 1;
struct SubRBTree
{
SubRBTree* left;
SubRBTree* right;
SubRBTree* parent;
int nData;
int color;
SubRBTree()
{
left = NULL;
right = NULL;
parent = NULL;
nData = 0;
color = BLACK;
}
SubRBTree(int nData,SubRBTree*nil):nData(nData)
{
left = nil;
right = nil;
parent = nil;
color = RED;
}
SubRBTree* RotateLeft(SubRBTree**pRoot,SubRBTree*nil)
{
SubRBTree* R = right;
right = right -> left;
if (R->left != nil)
R->left->parent = this;
if (this->parent == nil)
*pRoot = R;
else
{
if (this->parent->left == this)
this->parent->left = R;
else
this->parent->right = R;
}
R->parent = this->parent;
this->parent = R;
R->left = this;
return R;
}
SubRBTree* RotateRight(SubRBTree** pRoot, SubRBTree* nil)
{
SubRBTree* L = left;
left = left->right;
if (L->right != nil)
L->right->parent = this;
if (this->parent == nil)
*pRoot = L;
else
{
if (this->parent->left == this)
this->parent->left = L;
else
this->parent->right = L;
}
L->parent = this->parent;
this->parent = L;
L->right = this;
return L;
}
};
class RBTree
{
public:
RBTree();
~RBTree();
public:
bool Insert(const int nData);
void InsertEx(const int nData);
bool Delete(const int nData);
void Display()
{
PrintTree(root,0,-1);
}
private:
void InsertFixup(SubRBTree* pNode);
void InsertFixupEx(SubRBTree* pNode);
void DeleteFixup(SubRBTree* pNode);
SubRBTree* CreateNode(int nData);
void DeleteNode(SubRBTree* pNode);
SubRBTree* FindNode(const int nData);
SubRBTree* Maximum(SubRBTree* pNode);
SubRBTree* Minimum(SubRBTree* pNode);
void DeleteTree(SubRBTree* pNode);
void PrintTree(SubRBTree* pNode,int nDepth,int state) const;
private:
SubRBTree* root;
SubRBTree* nil;
int node_count;
};
RBTree::RBTree()
{
nil = new SubRBTree;
root = nil;
node_count = 0;
}
RBTree::~RBTree()
{
DeleteTree(root);
delete nil;
root = NULL;
nil = NULL;
}
SubRBTree* RBTree::CreateNode(int nData)
{
return new SubRBTree(nData, nil);
}
void RBTree::DeleteTree(SubRBTree* pNode)
{
if (pNode == nil)
return;
DeleteTree(pNode->left);
DeleteTree(pNode->right);
delete pNode;
pNode = NULL;
}
SubRBTree* RBTree::Maximum(SubRBTree* pNode)
{
while (pNode->right != nil)
pNode = pNode->right;
return pNode;
}
SubRBTree* RBTree::Minimum(SubRBTree* pNode)
{
while (pNode->left != nil)
pNode = pNode->left;
return pNode;
}
void RBTree::InsertEx(const int nData)
{
SubRBTree* pNewNode = CreateNode(nData);
SubRBTree* pPNewNode = nil;
SubRBTree* pTemp = root;
while (pTemp != nil)
{
pPNewNode = pTemp;
if (nData < pTemp->nData)
pTemp = pTemp->left;
else
pTemp = pTemp->right;
}
if (pPNewNode == nil)
root = pNewNode;
if (nData < pPNewNode->nData)
pPNewNode->left = pNewNode;
else
pPNewNode->right = pNewNode;
pNewNode->parent = pPNewNode;
InsertFixupEx(pNewNode);
}
bool RBTree::Insert(const int nData)
{
SubRBTree* pNewNode = CreateNode(nData);
SubRBTree* pPNewNode = nil;
SubRBTree* pTemp = root;
while (pTemp != nil)
{
pPNewNode = pTemp;
if (nData < pTemp->nData)
pTemp = pTemp->left;
else
pTemp = pTemp->right;
}
pNewNode->parent = pPNewNode;
if (pPNewNode == nil)
root = pNewNode;
else if (nData < pPNewNode->nData)
pPNewNode->left = pNewNode;
else
pPNewNode->right = pNewNode;
InsertFixup(pNewNode);
return true;
}
void RBTree::InsertFixup(SubRBTree* pNode)
{
while (pNode->parent->color == RED)
{
if (pNode->parent == pNode->parent->parent->left)
{
SubRBTree* pUNode = pNode->parent->parent->right;
if (pUNode->color == RED)
{
pNode->parent->color = BLACK;
pUNode->color = BLACK;
pNode->parent->parent->color = RED;
pNode = pNode->parent->parent;
}
else if (pNode == pNode->parent->right)
{
pNode = pNode->parent;
pNode->RotateLeft(&root, nil);
}
else
{
pNode->parent->color = BLACK;
pNode->parent->parent->color = RED;
pNode->parent->parent->RotateRight(&root, nil);
}
}
else
{
SubRBTree* pUNode = pNode->parent->parent->left;
if (pUNode->color == RED)
{
pNode->parent->color = BLACK;
pUNode->color = BLACK;
pNode->parent->parent->color = RED;
pNode = pNode->parent->parent;
}
else if (pNode == pNode->parent->left)
{
pNode = pNode->parent;
pNode->RotateRight(&root, nil);
}
else
{
pNode->parent->color = BLACK;
pNode->parent->parent->color = RED;
pNode->parent->parent->RotateLeft(&root, nil);
}
}
}
root->color = BLACK;
}
void RBTree::InsertFixupEx(SubRBTree* pNode)
{
while (pNode->parent->color==RED)
{
if (pNode->parent==pNode->parent->parent->left) {
SubRBTree* pUNode = pNode->parent->parent->right;
if (pUNode->color == RED)
{
pNode->parent->color = BLACK;
pUNode->color = BLACK;
pNode->parent->parent->color = RED;
pNode = pNode->parent->parent;
}
else if(pNode==pNode->parent->right)
{
pNode = pNode->parent;
pNode->RotateLeft(&root, nil);
}
else
{
pNode->parent->color = BLACK;
pNode->parent->parent->color = RED;
pNode->parent->parent->RotateRight(&root, nil);
}
}
else
{
SubRBTree* pUNode = pNode->parent->parent->left;
if (pUNode->color == RED)
{
pNode->parent->color = BLACK;
pUNode->color = BLACK;
pNode->parent->parent->color = RED;
pNode= pNode->parent->parent;
}
else if (pNode == pNode->parent->left)
{
pNode = pNode->parent;
pNode->RotateRight(&root, nil);
}
else
{
pNode->parent->color = BLACK;
pNode->parent->parent->color = RED;
pNode->parent->parent->RotateLeft(&root, nil);
}
}
}
root->color = BLACK;
}
bool RBTree::Delete(const int nData)
{
SubRBTree* pDeleteNode = FindNode(nData);
if (pDeleteNode == nil)
{
std::cout << "no Find" << std::endl;
return false;
}
DeleteNode(pDeleteNode);
return true;
}
SubRBTree* RBTree::FindNode(const int nData)
{
SubRBTree* pTemp = root;
while (pTemp != nil)
{
if (nData < pTemp->nData)
pTemp = pTemp->left;
else if (nData > pTemp->nData)
pTemp = pTemp->right;
else
return pTemp;
}
return nil;
}
void RBTree::DeleteNode(SubRBTree* pNode)
{
if (pNode->left != nil && pNode->right != nil)
{
SubRBTree*pNextNode=Minimum(pNode->right);
pNode->nData=pNextNode->nData;
pNode = pNextNode;
}
if (pNode->left != nil)
{
if (pNode->parent->left == pNode)
pNode->parent->left = pNode->left;
else
pNode->parent->right = pNode->left;
pNode->left->parent = pNode->parent;
pNode->left->color = BLACK;
delete pNode;
}
else if (pNode->right != nil)
{
if (pNode->parent->left == pNode)
pNode->parent->left = pNode->right;
else
pNode->parent->right = pNode->right;
pNode->right->parent = pNode->parent;
pNode->right->color = BLACK;
delete pNode;
}
else
{
if (pNode->color == RED)
{
if (pNode->parent->left == pNode)
pNode->parent->left = nil;
else
pNode->parent->right = nil;
delete pNode;
}
else
{
DeleteFixup(pNode);
if (pNode == root)
root = nil;
if (pNode == pNode->parent->left)
pNode->parent->left = nil;
else
pNode->parent->right = nil;
delete pNode;
}
}
return ;
}
void RBTree::DeleteFixup(SubRBTree* pNode)
{
while (pNode != root && pNode->color == BLACK)
{
if (pNode == pNode->parent->left)
{
SubRBTree* pBNode = pNode->parent->right;
if (pBNode->color = RED)
{
pBNode->color = BLACK;
pNode->parent->color = RED;
pNode->parent->RotateLeft(&root, nil);
pBNode = pNode->parent->right;
}
if (pBNode->left->color == BLACK && pBNode->right->color == BLACK)
{
pBNode->color = RED;
pNode = pNode->parent;
}
else if (pBNode->right->color == BLACK)
{
pBNode->left->color = BLACK;
pBNode->color = RED;
pBNode->RotateRight(&root, nil);
pBNode = pNode->parent->right;
}
else
{
pBNode->color = pNode->parent->color;
pNode->parent->color = BLACK;
pBNode->right->color = BLACK;
pNode->parent->RotateLeft(&root, nil);
pNode = root;
}
}
else
{
SubRBTree* pBNode = pNode->parent->left;
if (pBNode->color = RED)
{
pBNode->color = BLACK;
pNode->parent->color = RED;
pNode->parent->RotateRight(&root, nil);
pBNode = pNode->parent->left;
}
if (pBNode->left->color == BLACK && pBNode->right->color == BLACK)
{
pBNode->color = RED;
pNode = pNode->parent;
}
else if (pBNode->left->color == BLACK)
{
pBNode->right->color = BLACK;
pBNode->color = RED;
pBNode->RotateLeft(&root, nil);
pBNode = pNode->parent->left;
}
else
{
pBNode->color = pNode->parent->color;
pNode->parent->color = BLACK;
pBNode->left->color = BLACK;
pNode->parent->RotateRight(&root, nil);
pNode = root;
}
}
}
pNode->color = BLACK;
}
void RBTree::PrintTree(SubRBTree* pNode,int nDepth,int state) const
{
if (nil == pNode)
return;
PrintTree(pNode->left, nDepth + 1, 1);
for (int i = 0; i < nDepth; i++)
printf(" ");
if (state == 1)
printf("┌───");
else if (state == 0)
printf("└───");
std::cout << "[" << (pNode->color==RED ? "红:":"黑:") << pNode->nData << "]" << std::endl;
PrintTree(pNode->right, nDepth + 1, 0);
}
#include "MyRbTree.h"
#include <exception>
int main()
{
try
{
RBTree rbt;
for (int i = 1; i < 100; i++)
{
rbt.Insert(i);
}
rbt.Delete(4);
rbt.Display();
}
catch (std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}