红黑树的代码

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


这里是

红黑树的插入分析

这里是

红黑树的删除分析


接下来是我的代码:


#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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值