码迷,mamicode.com
首页 > 其他好文 > 详细

红黑树的代码

时间:2014-09-20 23:58:09      阅读:310      评论:0      收藏:0      [点我收藏+]

标签:c++

这里只写了最重要的插入和删除操作,其他的搜索等操作 就懒得写了。


这里是

红黑树的插入分析

这里是

红黑树的删除分析


接下来是我的代码:


#ifndef RBTREE_H
#define RBTREE_H

template <typename T>
struct RBNode{
	RBNode<T> *parent;
	RBNode<T> *left;
	RBNode<T> *right;
	T value;
	bool red;
	RBNode(const T& x,RBNode<T>* p){
		left = 0;
		value = x;
		red = true;
		parent = p;
		right = 0;
	}
};

template <typename T>
class RBTree{
private:
	RBNode<T> *root;
	void LRotation(RBNode<T>* p);//左旋和右旋
	void RRotation(RBNode<T>* p);
	bool AdjustColor(RBNode<T> *p);
	void AdjustAfterDelete(RBNode<T> *x,RBNode<T> *p);//必须要有一个父指针。
	void GetParentLinked(RBNode<T> *a,RBNode<T> *b);
	bool GetColorWithNULL(RBNode<T> *p){//由于没有哨兵节点,则需要考虑指针为空返回黑色。
		if(p)return p->red;
		else return false;
	}
public:
	RBTree(){
		root = 0;
	}
	bool Search(const T &x);
	bool Delete(const T &x);
	bool Insert(const T &x);


};

//改变其向下的指针的同时要更新其父指针。
template <typename T>
void RBTree<T>::LRotation(RBNode<T>* p){
	RBNode<T> *r = p->right;
	if(p->parent){
		if(p->parent->right == p) p->parent->right = r;
		else p->parent->left = r;
		r->parent = p->parent;		
	}else{
		root = r;
		r->parent = 0;
	}
	p->parent = r;
	if(r->left)r->left->parent = p;
	p->right = r->left;
	r->left = p;	
	return ;
}

template <typename T>
void RBTree<T>::RRotation(RBNode<T>* p){
	RBNode<T> *r = p->left;
	if(p->parent){
		if(p->parent->right == p) p->parent->right = r;
		else p->parent->left = r;
		r->parent = p->parent;
	}else{
		root = r;
		r->parent =0;
	}
	p->parent = r;
	if(r->right)r->right->parent = p;
	p->left = r->right;
	r->right = p;	
	return ;
}

template <typename T>
bool RBTree<T>::Insert(const T &x){
	if(!root){
		root = new RBNode<T>(x,0);
		root->red = false;
		return true;
	}
	RBNode<T>* p = root, *fa=root;
	while(p){
		fa = p;
		if(x <p->value)
			p = p->left;
		else if(x > p->value)
			p = p->right;
		else
			return false;
	}
	if(x < fa->value)	p = fa->left = new RBNode<T>(x,fa);
	else  p = fa-> right = new RBNode<T>(x,fa);
	AdjustColor(p);
	return true;
}
template <typename T>
bool RBTree<T>::AdjustColor(RBNode<T> *p){
	if( p == root){
		p->red = false;
		return true;
	}
	else if( ! p->parent->red )
		return true;
	else {
		RBNode<T>* uncle, *f, *g;
		f = p -> parent;
		g = f->parent;
		bool uncleColor;//由于叔叔节点可能为空
		if(f == g->left)
			uncle = g->right;
		else
			uncle = g->left;
		if(uncle)uncleColor = uncle->red;
		else uncleColor = false;
		if(uncleColor){
			uncle->red = false;
			f->red = false;
			g->red = true;
			//将祖父节点设为红色
			AdjustColor(g);
		}else{
			if(g->left == f){
				if(f->left == p){
					g->red = true;
					f->red = false;
					RRotation(g);
				}else{
					LRotation(f);
					AdjustColor(f);
				}
			}else{
				if(f->right == p){
					g->red = true;
					f->red = false;
					LRotation(g);
				}else{
					RRotation(f);
					AdjustColor(f);
				}
			}
		}

	}
	return true;
}

template <typename T>
void RBTree<T>::GetParentLinked(RBNode<T> *a,RBNode<T> *b){
	if(a == root){
		root = b;
		if(b)
			b->parent = 0;
		return;
	}
	if(a->parent->left == a){
		a->parent->left = b;
		if(b)
			b->parent = a->parent;
	}else{
		a->parent->right = b;
		if(b)
			b->parent = a->parent;
	}

}
template <typename T>
bool RBTree<T>::Delete(const T &x){
	RBNode<T> *p = root ,*s,*fa;
	if(!root)return false;
	while(p){
		if(p->value == x)break;
		else if(x < p->value)p = p->left;
		else p = p->right;
	}
	if(p){
		if( p->left &&  p->right){//当存在左右孩子时,向下旋转
			s = p->right;
			while(s->left){
				s = s->left;
			}
			int temp = p->value;
			p->value = s->value;
			s->value = temp;
			p = s;
		}
		if(p->red){//为红色叶子节点,直接删除
			GetParentLinked(p,p->left);
			delete p;
		}else{//为黑色时,将其红色子孩子替代他
			//由于之前已经向下旋转,则这里只有一种特殊可能,即单支情况删除黑色根节点。			
			fa = p->parent;//之后可能没有父节点。
			if(p->left){
				s = p->left;
				GetParentLinked(p,p->left);				
			}
			else {
				s = p->right;
				GetParentLinked(p,p->right);
			}
			delete p;
			AdjustAfterDelete(s,fa);
		}
		return true;
	}else return false;

	
}
template <typename T>
void RBTree<T>::AdjustAfterDelete(RBNode<T> *x ,RBNode<T> *p){
	if(p){//如果有父指针,则有四种情况。
		RBNode<T> *w ;
		bool inLeftTree = true;//标记左右情况,左右情况不同旋转方向以及判断方式也不同。
		if(p->left == x)w = p->right;
		else {
			w = p->left;
			inLeftTree = false;
		}
		if(w->red){
			w->red = false;
			p->red = true;
			if(inLeftTree)
				LRotation(p);//以p为支点进行旋转,不用考虑当前节点是否为空。
			else
				RRotation(p);
			AdjustAfterDelete(x,p);
		}else{
			if( !GetColorWithNULL(w->left) && !GetColorWithNULL(w->right) ){
				w->red = true;
				x = p;
				if(x ->red)x->red = false;//出错一次,要根据新的x节点进行判断。
				else	AdjustAfterDelete(x,x->parent);
			}else if(( inLeftTree && GetColorWithNULL(w->right) ) //情况4
				|| ( !inLeftTree && GetColorWithNULL(w->left) )  ){
					bool tempRed = p->red;
					p->red = w->red;
					w->red = tempRed;
					if(inLeftTree){
						w->right->red = false;						
						LRotation(p);
					}else{
						w->left->red = false;
						RRotation(p);
					}
			}else {//情况3
				w->red = true;
				if(inLeftTree){
					w->left->red = false;
					RRotation(w);
					AdjustAfterDelete(x,p);
				}else{
					w->right->red = false;
					LRotation(w);
					AdjustAfterDelete(x,p);
				}
			}
		}
	}else{//如果不存在父节点,则此节点为根节点,则置为黑色结束。
		if(x)
			x->red = false;
		return ;
	}

}


#endif


红黑树的代码

标签:c++

原文地址:http://blog.csdn.net/luo_xianming/article/details/39435655

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!