您的位置:首页 > 编程语言

红黑树研究记录-代码实现

2012-06-28 15:46 417 查看
代码可以根据《红黑树研究记录-实例》那篇文章的图来验证

main.cpp

#include <iostream.h>
#include "RBTree.h"

using namespace std;

int main(int argc, char *argv[])
{
int arr[20] = {12, 1, 9, 2, 0, 11, 7, 19, 4, 15, 18, 5, 14, 13, 10, 16, 6, 3, 8, 17};
RBTree *tree = new RBTree();
for(int i = 0; i < 20; i++)
tree->InsertNode(arr[i]);

std::cout<<"PreOrder:"<<std::endl;
tree->PreOrder();
std::cout<<"InOrder:"<<std::endl;
tree->InOrder();
std::cout<<"PostOrder:"<<std::endl;
tree->PostOrder();

std::cout<<std::endl<<"Delete Node:"<<std::endl;
cout<<"Delete 12:"<<endl;
tree->DeleteNode(12);
tree->PreOrder();
cout<<"Delete 1:"<<endl;
tree->DeleteNode(1);
tree->PreOrder();
cout<<"Delete 9:"<<endl;
tree->DeleteNode(9);
tree->PreOrder();
cout<<"Delete 2:"<<endl;
tree->DeleteNode(2);
tree->PreOrder();
cout<<"Delete 0:"<<endl;
tree->DeleteNode(0);
tree->PreOrder();
cout<<"Delete 11:"<<endl;
tree->DeleteNode(11);
tree->PreOrder();
cout<<"Delete 7:"<<endl;
tree->DeleteNode(7);
tree->PreOrder();
cout<<"Delete 19:"<<endl;
tree->DeleteNode(19);
tree->PreOrder();
cout<<"Delete 4:"<<endl;
tree->DeleteNode(4);
tree->PreOrder();
cout<<"Delete 15:"<<endl;
tree->DeleteNode(15);
tree->PreOrder();
cout<<"Delete 18:"<<endl;
tree->DeleteNode(18);
tree->PreOrder();
cout<<"Delete 5:"<<endl;
tree->DeleteNode(5);
tree->PreOrder();
cout<<"Delete 14:"<<endl;
tree->DeleteNode(14);
tree->PreOrder();
cout<<"Delete 13:"<<endl;
tree->DeleteNode(13);
tree->PreOrder();
cout<<"Delete 10:"<<endl;
tree->DeleteNode(10);
tree->PreOrder();
cout<<"Delete 6:"<<endl;
tree->DeleteNode(6);
tree->PreOrder();
cout<<"Delete 16:"<<endl;
tree->DeleteNode(16);
tree->PreOrder();
cout<<"Delete 3:"<<endl;
tree->DeleteNode(3);
tree->PreOrder();
cout<<"Delete 8:"<<endl;
tree->DeleteNode(8);
tree->PreOrder();
cout<<"Delete 17:"<<endl;
tree->DeleteNode(17);
tree->PreOrder();
return  0;
}


RBTree.h

#ifndef _RBTREE_HEADER_
#define _RBTREE_HEADER_

#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>

enum NodeColor{
RED,
BLACK
};

struct RBNode
{
int value;
NodeColor color;
RBNode *pParent;
RBNode *pLeft;
RBNode *pRight;
};

class RBTree
{
public:
RBTree();
~RBTree();

int InsertNode(int);
int DeleteNode(int);
RBNode *FindNode(int value);

void PreOrder();
void InOrder();
void PostOrder();
private:
void DeleteAll();
void TurnLeft(RBNode *pNode);
void TurnRight(RBNode *pNode);
int DeleteNode(RBNode *);
RBNode *GetSuccessor(RBNode *);
int InsertNode(RBNode *);
void DeleteFixup(RBNode *);
void InsertFixup(RBNode *);
private:
RBNode *m_root;
};

#endif


RBTree.cpp

#include "RBTree.h"
#include <deque>
#include <queue>

using namespace std;

RBTree::RBTree()
{
m_root = NULL;
}

RBTree::~RBTree()
{
DeleteAll();
}

void RBTree::TurnLeft(RBNode *pNode)
{
if(!pNode || !pNode->pParent)
return;
RBNode *pp = pNode->pParent->pParent;
if(pp)
if(pp->pLeft == pNode->pParent)
pp->pLeft = pNode;
else
pp->pRight = pNode;
pNode->pParent->pParent = pNode;
pNode->pParent->pRight = pNode->pLeft;
if(pNode->pLeft)
pNode->pLeft->pParent = pNode->pParent;
pNode->pLeft = pNode->pParent;
pNode->pParent = pp;
}

void RBTree::TurnRight(RBNode *pNode)
{
if(!pNode || !pNode->pParent)
return;
RBNode *pp = pNode->pParent->pParent;
if(pp)
if(pp->pLeft == pNode->pParent)
pp->pLeft = pNode;
else
pp->pRight = pNode;
pNode->pParent->pParent = pNode;
pNode->pParent->pLeft = pNode->pRight;
if(pNode->pRight)
pNode->pRight->pParent = pNode->pParent;
pNode->pRight = pNode->pParent;
pNode->pParent = pp;
}

void RBTree::DeleteAll()
{
if(!m_root)
std::cout<<"The tree is null"<<std::endl;
queue<RBNode*> qu;
qu.push(m_root);
while(qu.size() > 0)
{
RBNode *pCur = qu.front();
qu.pop();
std::cout<<"Delete:"<<pCur->value<<"("<<pCur->color<<"), "<<std::endl;
if(pCur->pLeft)
qu.push(pCur->pLeft);
if(pCur->pRight)
qu.push(pCur->pRight);
delete pCur;
pCur = NULL;
}
}

int RBTree::InsertNode(int value)
{
if(FindNode(value))
return -1;
RBNode *pNew = new RBNode();
pNew->value = value;
pNew->pParent = NULL;
pNew->color = RED;
pNew->pLeft = NULL;
pNew->pRight = NULL;

return InsertNode(pNew);
}

int RBTree::InsertNode(RBNode* pNode)
{
if(!pNode)
return -1;
if(!m_root)
{
m_root = pNode;
m_root->color = BLACK;
return 0;
}
RBNode *tmp = m_root;
RBNode *tmpParent = NULL;
while(tmp)
{
tmpParent = tmp;
if(tmp->value > pNode->value)
tmp = tmp->pLeft;
else
tmp = tmp->pRight;
}
if(tmpParent->value > pNode->value)
tmpParent->pLeft = pNode;
else
tmpParent->pRight = pNode;
pNode->pParent = tmpParent;

InsertFixup(pNode);
}

void RBTree::InsertFixup(RBNode *pNode)
{
if(!pNode)
return;
RBNode *pUncle = NULL;
while(pNode->pParent && pNode->pParent->color == RED)
{
if(pNode->pParent == pNode->pParent->pParent->pLeft)
{
pUncle = pNode->pParent->pParent->pRight;
if(pUncle && pUncle->color == RED)            //case 1
{
pNode->pParent->color = BLACK;
pUncle->color = BLACK;
pNode->pParent->pParent->color = RED;
pNode = pNode->pParent->pParent;
}
else
{
if(pNode == pNode->pParent->pRight)        //case 2
{
TurnLeft(pNode);
pNode = pNode->pLeft;
}
pNode->pParent->color = BLACK;            //case 3
pNode->pParent->pParent->color = RED;
TurnRight(pNode->pParent);
if(!pNode->pParent->pParent)
m_root = pNode->pParent;
}
}
else
{
pUncle = pNode->pParent->pParent->pLeft;
if(pUncle && pUncle->color == RED)                    //case 1
{
pNode->pParent->color = BLACK;
pUncle->color = BLACK;
pNode->pParent->pParent->color = RED;
pNode = pNode->pParent->pParent;
}
else
{
if(pNode == pNode->pParent->pLeft)        //case 2
{
TurnRight(pNode);
pNode = pNode->pRight;
}
pNode->pParent->color = BLACK;            //case 3
pNode->pParent->pParent->color = RED;
TurnLeft(pNode->pParent);
if(!pNode->pParent->pParent)
m_root = pNode->pParent;
}
}
}
m_root->color = BLACK;
}

int RBTree::DeleteNode(int value)
{
RBNode *pNode = NULL;
if(!(pNode = FindNode(value)))
return -1;
return DeleteNode(pNode);
}

RBNode *RBTree::GetSuccessor(RBNode *pNode)
{
RBNode *pThis = pNode->pRight;
while(pThis->pLeft)
pThis = pThis->pLeft;
return pThis;
}

int RBTree::DeleteNode(RBNode *pNode)
{
if(!pNode)
return -1;
RBNode *pDel = NULL;
RBNode *pThis = NULL;
//search the Node
if(!pNode->pLeft && !pNode->pRight)
{
pThis = pNode;
pDel = pNode;
}
else if(!pNode->pLeft || !pNode->pRight)
pDel = pNode;
else
pDel = GetSuccessor(pNode);

//delete the Node
if(pDel->pLeft)
pThis = pDel->pLeft;
else if(pDel->pRight)
pThis = pDel->pRight;
else
pThis = pDel;

if(pThis != pDel)
{
pThis->pParent = pDel->pParent;

if(!pDel->pParent)
m_root = pThis;
else if(pDel == pDel->pParent->pLeft)
pDel->pParent->pLeft = pThis;
else
pDel->pParent->pRight = pThis;
}
if(pDel != pNode)
pNode->value = pDel->value;
if(pDel->color == BLACK)
DeleteFixup(pThis);

if(pThis == pDel)
if(pDel == pDel->pParent->pLeft)
pDel->pParent->pLeft = NULL;
else
pDel->pParent->pRight = NULL;
if(pDel == m_root)
m_root = NULL;
delete pDel;
pDel = NULL;
}

void RBTree::DeleteFixup(RBNode *pNode)
{
RBNode *pBrother = NULL;
while(pNode != m_root && pNode->color == BLACK)
{
if(pNode == pNode->pParent->pLeft)
{
pBrother = pNode->pParent->pRight;
if(pBrother->color == RED)        //case 1
{
pBrother->color = BLACK;
pNode->pParent->color = RED;
TurnLeft(pBrother);
pBrother = pNode->pParent->pRight;
}
if((!pBrother->pLeft || pBrother->pLeft->color == BLACK)
&& (!pBrother->pRight || pBrother->pRight->color == BLACK))        //case 2
{
pBrother->color = RED;
pNode = pNode->pParent;
}
else
{
if(!pBrother->pRight || pBrother->pRight->color == BLACK)        //case 3
{
pBrother->pLeft->color = BLACK;
pBrother->color = RED;
TurnRight(pBrother->pLeft);
pBrother = pNode->pParent->pRight;
}
pBrother->color = pNode->pParent->color;    //case 4
pNode->pParent->color = BLACK;
pBrother->pRight->color = BLACK;
TurnLeft(pBrother);
pNode = m_root;
}
}
else
{
pBrother = pNode->pParent->pLeft;
if(pBrother->color == RED)        //case 1
{
pBrother->color = BLACK;
pNode->pParent->color = RED;
TurnRight(pBrother);
pBrother = pNode->pParent->pLeft;
}
if((!pBrother->pLeft || pBrother->pLeft->color == BLACK)
&& (!pBrother->pRight || pBrother->pRight->color == BLACK))    //case 2
{
pBrother->color = RED;
pNode = pNode->pParent;
}
else
{
if(!pBrother->pLeft || pBrother->pLeft->color == BLACK)        //case 3
{
pBrother->pRight->color = BLACK;
pBrother->color = RED;
TurnLeft(pBrother->pRight);
pBrother = pNode->pParent->pLeft;
}
pBrother->color = pNode->pParent->color;
pNode->pParent->color = BLACK;
pBrother->pLeft->color = BLACK;
TurnRight(pBrother);
pNode = m_root;
}
}
}
pNode->color = BLACK;
}

RBNode *RBTree::FindNode(int value)
{
if(!m_root)
return NULL;
RBNode *tmp = m_root;
while(tmp)
{
if(value > tmp->value)
tmp = tmp->pRight;
else if(value < tmp->value)
tmp = tmp->pLeft;
else
break;
}
return tmp;
}

void RBTree::PreOrder()
{
if(!m_root)
{
std::cout<<"The tree is null"<<std::endl;
return;
}
queue<RBNode*> qu;
qu.push(m_root);
while(qu.size() > 0)
{
RBNode *pCur = qu.front();
qu.pop();
std::cout<<pCur->value<<"("<<pCur->color<<"), ";
if(pCur->pLeft)
qu.push(pCur->pLeft);
if(pCur->pRight)
qu.push(pCur->pRight);
}
std::cout<<std::endl;
}

void RBTree::InOrder()
{
if(!m_root)
{
std::cout<<"The tree is null"<<std::endl;
return;
}

deque<RBNode*> de;
RBNode *pCur = m_root;
bool bPush = false;

while(pCur)
{
if(pCur->pLeft && !bPush)
{
de.push_back(pCur);
pCur = pCur->pLeft;
continue;
}
std::cout<<pCur->value<<"("<<pCur->color<<"), ";

if(pCur->pRight)
{
pCur = pCur->pRight;
bPush = false;
}
else
{
if(de.size() == 0)
break;
pCur = de.back();
de.pop_back();
bPush = true;
}
}
std::cout<<std::endl;
}

void RBTree::PostOrder()
{
if(!m_root)
{
std::cout<<"The tree is null"<<std::endl;
return;
}
deque<RBNode*> de;
int flag = 0;
RBNode *pCur = m_root;
while(pCur)
{
if(pCur->pLeft && flag < 1)
{
de.push_back(pCur);
pCur = pCur->pLeft;
continue;
}
if(pCur->pRight && flag < 2)
{
de.push_back(pCur);
pCur = pCur->pRight;
flag = 0;
continue;
}
std::cout<<pCur->value<<"("<<pCur->color<<"), ";

if(de.size() == 0)
break;
RBNode *pParent = de.back();
de.pop_back();

if(pCur == pParent->pLeft)
{
flag = 1;
pCur = pParent;
}
else if(pCur == pParent->pRight)
{
flag = 2;
pCur = pParent;
}
}
std::cout<<std::endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: