ADT—红黑树

Posted on 2010-04-03 22:14  625747  阅读(404)  评论(0)    收藏  举报

 

代码
#pragma once
#include
<iostream>
using namespace std;

typedef
enum _color
{
RED,
BLACK
}COLOR;

class RBNode
{
public:
RBNode(
void):key(0),parent(NULL),left(NULL),right(NULL),color(BLACK){}
RBNode(
int value);
public:
~RBNode(void);
public:
int key;
RBNode
*parent;
RBNode
*left;
RBNode
*right;
COLOR color;
};

class RBTree
{
public:
RBTree(
void);
~RBTree(void);
void Insert(int value);
void Delete(int value);
RBNode
* Max(RBNode *pNode);
RBNode
* Min(RBNode *pNode);
RBNode
* Find(int value);
RBNode
* Successor(RBNode *pNode);

void inorderTravel();
void preorderTravel();
void postorderTravel();

private:
void inorder(RBNode *p);
void preorder(RBNode *p);
void postorder(RBNode *p);

void InsertFixUp(RBNode *pNode);
void DeleteFixUp(RBNode *pNode);
void LeftRotate(RBNode *pNode);
void RightRotate(RBNode *pNode);
private:
RBNode
* m_pRoot;
RBNode
* nil;
};

 

代码
#include "RBTree.h"


RBNode::RBNode(
int value)
{

color
=BLACK;
key
=value;
left
=0;
right
=0;
parent
=0;
}

RBTree::RBTree()
{
nil
=new RBNode;
nil
->color=BLACK;
nil
->key=123456;
nil
->left=0;
nil
->right=0;
nil
->parent=0;
m_pRoot
= NULL;
}

RBTree::
~RBTree(void)
{
}

void RBTree::Insert(int value)
{
if(m_pRoot==NULL)
{
RBNode
*pNew=new RBNode();
pNew
->key=value;
pNew
->parent=nil;
pNew
->left=nil;
pNew
->right=nil;
pNew
->color = BLACK;
m_pRoot
=pNew;
}
else
{
RBNode
*py;
RBNode
*px=m_pRoot;
while(px!=nil)
{
py
=px;
if(value<px->key)
{
px
=px->left;
}
else if(value>px->key)
{
px
=px->right;
}
else
{
py
=nil;
}
}
if(py!=nil)
{
RBNode
*pNew=new RBNode(value);
pNew
->parent=py;
if(value<py->key)
{
py
->left=pNew;
}
else
{
py
->right=pNew;
}
pNew
->left=nil;
pNew
->right=nil;
pNew
->color=RED;

if(py!=this->m_pRoot)
InsertFixUp(pNew);
}
}
}

void RBTree::InsertFixUp(RBNode *pNode)
{
while(pNode->parent->color==RED)
{
RBNode
*py;
if(pNode->parent==pNode->parent->parent->left)
{
py
=pNode->parent->parent->right;
//Case 1: z's uncle y is red
if(py->color==RED)
{
pNode
->parent->color=BLACK;
py
->color=BLACK;
pNode
->parent->parent->color=RED;
pNode
=pNode->parent->parent;
}
else
{
//Case 2: z's uncle y is black and z is a right child
if(pNode==pNode->parent->right)
{
pNode
=pNode->parent;
this->LeftRotate(pNode);
}
//Case 3: z's uncle y is black and z is a left child
pNode->parent->color=BLACK;
pNode
->parent->parent->color=RED;
this->RightRotate(pNode->parent->parent);
}
}
else
{
py
=pNode->parent->parent->left;
if(py->color==RED)
{
pNode
->parent->color=BLACK;
py
->color=BLACK;
pNode
->parent->parent->color=RED;
}
else
{
if(pNode==pNode->parent->left)
{
pNode
=pNode->parent;
this->RightRotate(pNode);
}
pNode
->parent->color=BLACK;
pNode
->parent->parent->color=RED;
this->LeftRotate(pNode->parent->parent);
}
}
}
this->m_pRoot->color=BLACK;
}

void RBTree::LeftRotate(RBNode *pNode)
{
if(pNode->right!=nil)
{
RBNode
*y=pNode->right;
pNode
->right=y->left;
if(nil!=y->left)
{
y
->left->parent=pNode;
}
y
->parent=pNode->parent;
if(nil==pNode->parent)
{
m_pRoot
=y;
}
else if(pNode=pNode->parent->left)
{
pNode
->parent->left=y;
}
else
{
pNode
->parent->right=y;
}
y
->left=pNode;
pNode
->parent=y;
}
}

void RBTree::RightRotate(RBNode *pNode)
{
if(nil!=pNode->left)
{
RBNode
*y=pNode->left;
pNode
->left=y->right;
if(nil!=y->right)
{
y
->right->parent=pNode;
}
y
->parent=pNode->parent;
if(nil==pNode->parent)
{
m_pRoot
=y;
}
else if(pNode->parent->left==pNode)
{
pNode
->parent->left=y;
}
else
{
pNode
->parent->right=y;
}
y
->right=pNode;
pNode
->parent=y;
}
}

RBNode
* RBTree::Max(RBNode *pNode)
{
while(pNode->left!=nil)
{
pNode
=pNode->left;
}
return pNode;
}

RBNode
* RBTree::Min(RBNode *pNode)
{
while(pNode->right!=nil)
{
pNode
=pNode->right;
}
return pNode;
}


RBNode
* RBTree::Successor(RBNode *pNode)
{
if(pNode->right!=nil)
return Min(pNode->right);
RBNode
* py=pNode->parent;
while(py!=nil&&pNode==py->right)
{
pNode
=py;
py
=py->parent;
}
return py;
}

RBNode
* RBTree::Find(int value)
{
if(m_pRoot==nil)
return NULL;
else
{
RBNode
*pNode=m_pRoot;
while(pNode->key!=value&&pNode!=nil)
{
if(value<pNode->key)
{
pNode
=pNode->left;
}
else
{
pNode
=pNode->right;
}
}
return pNode==nil?NULL:pNode;
}
}

void RBTree::Delete(int value)
{
RBNode
*pNode=Find(value);
RBNode
*py,*px;
if(pNode!=NULL)
{
if(pNode->left==nil||pNode->right==nil)
{
py
=pNode;
}
else
{
py
=this->Successor(pNode);
}
if(py->left!=nil)
{
px
=py->left;
}
else
{
px
=py->right;
}
px
->parent=py->parent;
if(py->parent==nil)
{
m_pRoot
=px;
}
else if(py->parent->left=py)
{
py
->parent->left=px;
}
else
{
py
->parent->right=px;
}
bool isFix=py->color==BLACK?true:false;
if(py==pNode)
{
py
->parent=pNode->parent;
py
->left=pNode->left;
py
->right=pNode->right;
py
->color=pNode->color;
// delete pNode;
}
if(isFix)
DeleteFixUp(px);
}
}

void RBTree::DeleteFixUp(RBNode *pNode)
{
if(pNode==NULL||pNode==nil)
return;
while(pNode!=this->m_pRoot&&pNode->color==BLACK)
{
if(pNode==pNode->parent->left)
{
RBNode
*pw=pNode->parent->right;
//case1:x's sibling w is red
if(pw->color=RED)
{
pNode
->parent->color=RED;
pw
->color=BLACK;
this->LeftRotate(pNode->parent);
pw
=pNode->parent->right;
}
//case2:x's sibling w is black, and both of w's children are black
if(pw->left->color==BLACK&&pw->right->color==BLACK)
{
pw
->color=RED;
pNode
=pNode->parent;
}
else
{
//case3:x's sibling w is black, w's left child is red, and w's right child is black
if(pw->right->color==BLACK)
{
pw
->left->color=BLACK;
pw
->color=RED;
this->RightRotate(pw);
pw
=pNode->parent->right;
}
//case4:x's sibling w is black, and w's right child is red
pw->color=pNode->parent->color;
pNode
->parent->color=BLACK;
pw
->right->color=BLACK;
this->LeftRotate(pNode->parent);
pNode
=this->m_pRoot;
}
}
else
{
RBNode
*pw=pNode->parent->left;
if(pw->color==RED)
{
pNode
->parent->color=RED;
pw
->color=BLACK;
this->RightRotate(pNode->parent);
pw
=pNode->parent->left;
}
if(pw->right->color==BLACK&&pw->left->color==BLACK)
{
pw
->color=RED;
pNode
=pNode->parent;
}
else
{
if(pw->left->color==BLACK)
{
pw
->color=RED;
pw
->left->color=BLACK;
this->LeftRotate(pw);
pw
=pNode->parent->left;
}
pw
->color=pNode->parent->color;
pNode
->parent->color=BLACK;
pw
->left->color=RED;
this->RightRotate(pNode);
pNode
=this->m_pRoot;
}
}
}
pNode
->color=BLACK;
}

//中序遍历
void RBTree::inorderTravel()
{
inorder (m_pRoot);
}
//前序遍历
void RBTree::preorderTravel ()
{
preorder(m_pRoot);
}

//后序遍历
void RBTree::postorderTravel ()
{
postorder(m_pRoot);
}


void RBTree::inorder (RBNode *p)
{
if(p!=nil)
{
inorder(p
->left );
if(p->color==RED)
if(p->left->color==RED||p->right->color==RED)
cout
<<"wrong"<<" ";
cout
<<p->key <<" ";
inorder(p
->right);
}
}
void RBTree::preorder(RBNode *p)
{
if(p!=nil)
{
cout
<<p->key <<" ";
preorder(p
->left );
preorder(p
->right );
}
}

void RBTree::postorder (RBNode *p)
{
if(p!=nil)
{
postorder(p
->left);
postorder(p
->right);
cout
<<p->key <<" ";
}
}

int main()
{
RBTree rbt;
rbt.Insert (
3);
rbt.Insert (
434);
rbt.Insert (
4);
rbt.Insert (
55);

rbt.inorderTravel ();
cout
<<"后序遍历"<<endl;
rbt.postorderTravel ();


cout
<<"test "<<endl;
}