这是c++实现的红黑树,主要思路跟前一篇c语言的一样,主要是设计方式的不同,通过这两篇博客也能比较一下面向过程和面向对象之间的区别与联系。
本例单独5个函数:
Node.h
#ifndef NODE_H_
#define NODE_H_
typedef int EleType;
//定义红黑树结点颜色颜色类型
enum Color { RED, BLACK };
class Node
{
public:
Node(); //默认构造函数
Node( Node* p, Node* l, Node* r, EleType k, Color c );
Node* getParent();
void setParent( Node* x );
Node* getLeft();
void setLeft( Node* x );
Node* getRight();
void setRight( Node* x );
EleType getKey();
void setKey( EleType k );
Color getColor();
void setColor( Color c );
private:
Node *parent;
Node *left;
Node *right;
EleType key;
Color color;
};
#endif /* NODE_H_ */
Node.cpp
#include <iostream>
#include "Node.h"
Node::Node():parent(NULL), left(NULL), right(NULL), key(0), color(BLACK){}
Node::Node( Node* p, Node* l, Node* r, EleType k, Color c ) :
parent(p), left(l), right(r), key(k), color(c){}
Node* Node::getParent()
{
return parent;
}
void Node::setParent( Node* x )
{
parent = x;
}
Node* Node::getLeft()
{
return left;
}
void Node::setLeft( Node* x )
{
left = x;
}
Node* Node::getRight()
{
return right;
}
void Node::setRight( Node* x )
{
right = x;
}
EleType Node::getKey()
{
return key;
}
void Node::setKey( EleType k )
{
key = k;
}
Color Node::getColor()
{
return color;
}
void Node::setColor( Color x )
{
color = x;
}
RBTree.h
#ifndef RBTREE_H_
#define RBTREE_H_
#include "Node.h"
class RBTree
{
public:
RBTree();
~RBTree();
void rb_insert( EleType k );
void rb_delete( EleType k );
void rb_display();
private:
Node* root;
Node* nil;
Node* rb_createNode( EleType key ); //构造一个结点,值为key
void rb_search( EleType key ); //查找值为key的结点
Node* rb_search( Node* r, EleType key ); //递归查找值为key的结点
Node* rb_maximum( Node* x ); //给定结点为根的子树中的最大结点
Node* rb_minimum( Node* x ); //给定结点为根的子树中的最小结点
Node* rb_successor( Node* x ); //后继结点
void left_rotate( Node* x ); //左旋
void right_rotate( Node* x ); //右旋
void rb_insertFixup( Node* x ); //插入结点后的调整
void rb_deleteFixup( Node* x ); //删除结点后的调整
void rb_display( Node* x ); //打印整棵红黑树,递归实现
};
#endif /* RBTREE_H_ */
RBTree.cpp
#include <iostream>
#include "RBTree.h"
using namespace std;
RBTree::RBTree()
{
nil = new Node();
nil->setParent( nil );
nil->setLeft( nil );
nil->setRight( nil );
nil->setKey( 0 );
nil->setColor( BLACK );
root = nil;
}
Node* RBTree::rb_createNode( int key )
{
Node* node = new Node();
node->setParent( nil );
node->setLeft( nil );
node->setRight( nil );
node->setKey( key );
node->setColor( RED );
return node;
}
void RBTree::rb_display()
{
rb_display( root ); //递归调用带参数的函数rb_display()
cout << endl;
}
void RBTree::rb_display( Node* x )
{
if( x != nil )
{
rb_display( x->getLeft() );
cout << x->getKey() << " ,color is ";
if( x->getColor() )
cout << "BLACK" << endl;
else
cout << "RED" << endl;
rb_display( x->getRight() );
}
}
Node* RBTree::rb_search( Node* r, int key )
{
if( (r == nil) || (r->getKey() == key) )
return r;
if( key < r->getKey() )
return rb_search( r->getLeft(), key );
else
return rb_search( r->getRight(), key );
}
Node* RBTree::rb_maximum( Node* x )
{
if( x->getRight() == nil )
return x;
else
return rb_maximum( x->getRight() );
}
Node* RBTree::rb_minimum( Node* x )
{
if( x->getLeft() == nil )
return x;
else
return rb_minimum( x->getLeft() );
}
Node* RBTree::rb_successor( Node* x )
{
if( x->getRight() != nil )
return rb_minimum( x->getRight() );
Node* y = x->getParent();
while( ( y!=nil ) && ( x==y->getRight() ) )
{
x = y;
y->setParent( y );
}
return y;
}
void RBTree::left_rotate( Node* x )
{
Node* y;
if( x->getRight() == nil )
{
cout << "have no right child,rotation cancel." << endl;
return;
}
y = x->getRight();
x->setRight( y->getLeft() );
if( y->getLeft() != nil )
y->getLeft()->setParent( x );
y->setParent( x->getParent() );
if( x->getParent() == nil )
root = y;
else if( x == x->getParent()->getLeft() )
x->getParent()->setLeft( y );
else
x->getParent()->setRight( y );
y->setLeft( x );
x->setParent( y );
}
void RBTree::right_rotate( Node* x )
{
Node* y;
if( x->getLeft() == nil )
{
cout << "have no left child,rotation cancel." << endl;
return;
}
y = x->getLeft();
x->setLeft( y->getRight() );
if( y->getRight() != nil )
y->getRight()->setParent( x );
y->setParent( x->getParent() );
if( x->getParent() == nil )
root = y;
else if( x == x->getParent()->getLeft() )
x->getParent()->setLeft( y );
else
x->getParent()->setRight( y );
y->setRight( x );
x->setParent( y );
}
void RBTree::rb_insert( EleType key )
{
Node* y = nil;
Node* x = root;
Node* z = rb_createNode( key );
z->setKey( key );
while( x != nil )
{
y = x;
if ( key < x->getKey() )
x = x->getLeft();
else
x = x->getRight();
}
z->setParent( y );
if ( y == nil )
root = z;
else if ( z->getKey() < y->getKey() )
y->setLeft( z );
else
y->setRight( z );
z->setLeft( root->getParent() );
z->setRight( root->getParent() );
z->setColor( RED );
rb_insertFixup( z );
}
void RBTree::rb_insertFixup( Node* z )
{
while( z->getParent()->getColor() == RED )
{
if( z->getParent() == z->getParent()->getParent()->getLeft() )
{
Node* y = z->getParent()->getParent()->getRight();
if( y->getColor() == RED )
{
z->getParent()->setColor( BLACK );
y->setColor( BLACK );
z->getParent()->getParent()->setColor( RED );
z = z->getParent()->getParent();
}
else
{
if( z == z->getParent()->getRight() )
{
z = z->getParent();
left_rotate( z );
}
z->getParent()->setColor( BLACK );
z->getParent()->getParent()->setColor( RED );
right_rotate( z->getParent()->getParent() );
}
}
else
{
Node* y = z->getParent()->getParent()->getLeft();
if( y->getColor() == RED )
{
z->getParent()->setColor( BLACK );
y->setColor( BLACK );
z->getParent()->getParent()->setColor( RED );
z = z->getParent()->getParent();
}
else
{
if( z == z->getParent()->getLeft() )
{
z = z->getParent();
right_rotate( z );
}
z->getParent()->setColor( BLACK );
z->getParent()->getParent()->setColor( RED );
left_rotate( z->getParent()->getParent() );
}
}
}
root->setColor( BLACK );
}
void RBTree::rb_delete( EleType key )
{
Node* z = rb_search( root, key ); //要删除值所在结点
if( z == nil )
{
cout << "Not in the tree" << endl;
return;
}
else
{
Node* x = nil; //删除结点的子结点
Node* y = nil; //删除的结点
if( (z->getLeft() == nil) || (z->getRight() == nil) )
y = z;
else
y = rb_successor( z );
if ( y->getLeft() != nil )
x = y->getLeft();
else
x = y->getRight();
x->setParent( y->getParent() );
if ( y->getParent() == nil )
root = x;
else if ( y == x->getParent()->getLeft() )
y->getParent()->setLeft( x );
else
y->getParent()->setRight( x );
if( y != z )
z->setKey( y->getKey() );
if( y->getColor() == BLACK )
rb_deleteFixup( x );
delete y;
}
}
void RBTree::rb_deleteFixup( Node* x )
{
Node* w;
while ( (x != root) && (x->getColor() == BLACK) )
{
if ( x == x->getParent()->getLeft() )
{
w = x->getParent()->getRight();
if (w->getColor() == RED)
{
w->setColor( BLACK );
x->getParent()->setColor( RED );
left_rotate( x->getParent() );
w = x->getParent()->getRight();
}
if ( (w->getLeft()->getColor() == BLACK) && (w->getRight()->getColor() == BLACK) )
{
w->setColor( RED );
x = x->getParent();
}
else
{
if ( w->getRight()->getColor() == BLACK )
{
w->getLeft()->setColor( BLACK );
w->setColor( RED );
right_rotate( w );
w = x->getParent()->getRight();
}
w->setColor( x->getParent()->getColor() );
x->getParent()->setColor( BLACK );
w->getRight()->setColor( BLACK );
left_rotate( x->getParent() );
x = root;
}
}
else
{
w = x->getParent()->getLeft();
if ( w->getColor() == RED )
{
w->setColor( BLACK );
x->getParent()->setColor( RED );
right_rotate( x->getParent() );
w = x->getParent()->getRight();
}
if( (w->getRight()->getColor() == BLACK) && (w->getLeft()->getColor() == BLACK) )
{
w->setColor( RED );
x = x->getParent();
}
else
{
if( w->getLeft()->getColor() == BLACK )
{
w->getRight()->setColor( BLACK );
w->setColor( RED );
left_rotate( w );
w = x->getParent()->getLeft();
}
w->setColor( x->getParent()->getColor() );
x->getParent()->setColor( BLACK );
w->getLeft()->setColor( BLACK );
right_rotate( x->getParent() );
x = root;
}
}
}
x->setColor( BLACK );
}
RBTree::~RBTree()
{
delete nil;
delete root;
}
main.cpp
#include <iostream>
#include "RBTree.h"
int main()
{
RBTree rbtree;
rbtree.rb_insert( 12 );
rbtree.rb_insert( 1 );
rbtree.rb_insert( 9 );
rbtree.rb_insert( 2 );
rbtree.rb_insert( -10 );
rbtree.rb_display();
rbtree.rb_delete( 2 );
rbtree.rb_display();
rbtree.rb_delete( 10 );
rbtree.rb_display();
return 0;
}