红黑树的代码

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


这里是

红黑树的插入分析

这里是

红黑树的删除分析


接下来是我的代码:


#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 语言红黑树代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义红黑树节点结构体 typedef struct RBNode { int data; int color; struct RBNode *left; struct RBNode *right; struct RBNode *parent; } RBNode; // 定义红黑树结构体 typedef struct RBTree { RBNode *root; } RBTree; // 定义常量 #define RED 0 #define BLACK 1 // 初始化红黑树 void init(RBTree *tree) { tree->root = NULL; } // 树的左旋操作 void leftRotate(RBTree *tree, RBNode *node) { RBNode *right = node->right; node->right = right->left; if (right->left != NULL) { right->left->parent = node; } right->parent = node->parent; if (node->parent == NULL) { tree->root = right; } else if (node == node->parent->left) { node->parent->left = right; } else { node->parent->right = right; } right->left = node; node->parent = right; } // 树的右旋操作 void rightRotate(RBTree *tree, RBNode *node) { RBNode *left = node->left; node->left = left->right; if (left->right != NULL) { left->right->parent = node; } left->parent = node->parent; if (node->parent == NULL) { tree->root = left; } else if (node == node->parent->right) { node->parent->right = left; } else { node->parent->left = left; } left->right = node; node->parent = left; } // 插入节点 void insert(RBTree *tree, int data) { RBNode *node = (RBNode *)malloc(sizeof(RBNode)); node->data = data; node->color = RED; node->left = NULL; node->right = NULL; node->parent = NULL; RBNode *parent = NULL; RBNode *current = tree->root; while (current != NULL) { parent = current; if (node->data < current->data) { current = current->left; } else { current = current->right; } } node->parent = parent; if (parent == NULL) { tree->root = node; } else if (node->data < parent->data) { parent->left = node; } else { parent->right = node; } while (node != tree->root && node->parent->color == RED) { if (node->parent == node->parent->parent->left) { RBNode *uncle = node->parent->parent->right; if (uncle != NULL && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; leftRotate(tree, node); } node->parent->color = BLACK; node->parent->parent->color = RED; rightRotate(tree, node->parent->parent); } } else { RBNode *uncle = node->parent->parent->left; if (uncle != NULL && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->left) { node = node->parent; rightRotate(tree, node); } node->parent->color = BLACK; node->parent->parent->color = RED; leftRotate(tree, node->parent->parent); } } } tree->root->color = BLACK; } // 中序遍历 void inorder(RBNode *node) { if (node != NULL) { inorder(node->left); printf("%d ", node->data); inorder(node->right); } } int main() { RBTree tree; init(&tree); insert(&tree, 10); insert(&tree, 20); insert(&tree, 30); insert(&tree, 15); insert(&tree, 18); insert(&tree, 25); insert(&tree, 5); inorder(tree.root); return 0; } ``` 这段代码使用了结构体定义红黑树节点和红黑树,以及一些常量和函数来实现红黑树的插入和中序遍历操作。代码中的 `insert` 函数使用了红黑树的插入算法来插入新的节点,并维护红黑树的性质。在 `main` 函数中,我们插入了一些数据并进行了中序遍历操作,以验证红黑树的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值