《算法导论》学习笔记(4)——红黑树(c++语言实现)

这是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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值