红黑树插入




红黑树的性质:
    1.每个节点不是红就是黑
    2.根节点为黑色
    3.如果节点为红,其子节点必须为黑
    4.任一节点至NULL(树尾端)的任何路径,所含之黑节点树必须相同
    性质总结一句话:一头一脚黑,黑同红不连
 

 规则1就不用说了,由规则2,root->color=NULL;由规则4,可知新增节点为红;由规则3可知,新增节点之父必为黑,
 当新节点插入不符合上述规则时,进行调整



经整理后,插入分为3种:
1.插入节点为父节点的左子树,叔节点为黑或空节点
2.插入节点为父节点的右子树,叔节点为黑或空节点
3.叔节点为红

#pragma once


typedef enum { RED = 0, BLACK } COLOR;

template<class Type>
class RBTree;

template<class Type>
class RBNode
{
	friend class RBTree<Type>;
public:
	RBNode() : data(Type()), color(RED), leftChild(NULL), rightChild(NULL), parent(NULL)
	{}
	RBNode(Type d, RBNode<Type>*left = NULL, RBNode<Type>*right = NULL, RBNode<Type>*pr = NULL)
		:data(d), color(RED), leftChild(left), rightChild(right), parent(pr)
	{}
	~RBNode()
	{}
private:
	Type data;
	RBNode<Type> *leftChild;
	RBNode<Type> *rightChild;
	RBNode<Type> *parent;
	COLOR color;
};

template<class Type>
class RBTree
{
public:
	RBTree() :root(NULL)
	{}
public:
	bool Insert(const Type& x)
	{
		return Insert(root, x);
	}
protected:
	bool Insert(RBNode<Type> *&t, const Type &v)
	{
		RBNode<Type> *p = t;
		RBNode<Type> *pr = NULL;
		while (p != NULL)
		{
			if (v == p->data)
				return false;
			pr = p;
			if (v < p->data)
				p = p->leftChild;
			else
				p = p->rightChild;
		}
		RBNode<Type> *x = new RBNode<Type>(v);
		x->parent = pr;
		if (pr == NULL)
		{
			t = x;
			t->color = BLACK;
			return true;
		}
		if (pr->data > x->data)
			pr->leftChild = x;
		else
			pr->rightChild = x;

		_Insert_Fixup(t, x);
		return true;
	}
public:
	void sort()
	{
		sort(root);
	}

protected:
	void sort(RBNode<Type>*t)const
	{
		if (t != NULL)
		{
			sort(t->leftChild);
			cout << t->data <<":"<<t->color<<" ";
			sort(t->rightChild);

		}
	}
protected:
	void _Insert_Fixup(RBNode<Type>*&t, RBNode<Type>*x)
	{
		RBNode<Type>*s;
		while (x->parent!=NULL&&x->parent->color == RED)//父节点为红色
		{
			if (x->parent == x->parent->parent->leftChild)//父亲为他父亲的父亲的左孩子
			{
				s = x->parent->parent->rightChild;//叔父为他父亲的父亲的右孩子
				/*if ((x == x->parent->leftChild&&s == NULL) ||
					(x == x->parent->leftChild&&s != NULL&&s->color == BLACK))//1.插入节点为他父亲的左孩子,且叔父节点为空或者叔父节点不为空但颜色为黑
				{
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					RotateR(x->parent->parent);
				}
				else if ((x == x->parent->rightChild&&s == NULL) ||
					(x == x->parent->rightChild&&s != NULL&&s->color == BLACK))//2.插入节点为他父亲的右孩子,且叔父节点为空或者叔父节点不为空但颜色为黑
				{
					x->color = BLACK;
					x->parent->parent->color = RED;
					RotateL(x->parent);
					RotateR(x->parent);
				}*/

				//将上面的2种情况进行改进(更精简化)
			if((s != NULL&&s->color == BLACK)||s == NULL)
				{
					if (x == x->parent->rightChild)//2.
					{
						x = x->parent;
						RotateL(x);
					}
					//1.
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					RotateR(x->parent->parent);
				}
				


#if 0			
				else if (x == x->parent->leftChild&&s != NULL&&s->color == RED)//3.插入节点为他父亲的左孩子,且叔父节点不为空但颜色为红
				{
					x->color = BLACK;
					RotateR(x->parent->parent);
					if (x->parent->parent != NULL &&x->parent->parent->color == RED)
					{
						x = x->parent;
						continue;
					}
				}
				else if (x == x->parent->rightChild&&s != NULL&&s->color == RED)//4.插入节点为他父亲的右孩子,且叔父节点不为空但颜色为红
				{
					x->parent->color = BLACK;
					RotateL(x->parent);
					RotateR(x->parent);
					if (x->parent != NULL &&x->parent->color == RED)
					{
						continue;
					}
				}
#endif
				//对上面3,4情况进行改进,即不管x为其父的左孩子还是右孩子,将其父和叔叔的颜色改为黑色,其父亲的父亲改为红色,然后让x指向其父亲的父亲,循环(最后树的形状与之前不同)
				else if(s!=NULL&&s->color==RED)
				{
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					s->color = BLACK;
					x = x->parent->parent;
					continue;
				}
			break;
				
			}
			else//与上面相反
			{
				s = x->parent->parent->leftChild;
				/*
				if ((x == x->parent->rightChild&&s == NULL) ||
					(x == x->parent->rightChild&&s != NULL&&s->color == BLACK))
				{
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					RotateL(x->parent->parent);

				}
				else if 
					((x == x->parent->leftChild&&s == NULL) ||
					(x == x->parent->leftChild&&s != NULL&&s->color == BLACK))
				{
					x->color = BLACK;
					x->parent->parent->color = RED;
					RotateR(x->parent);
					RotateL(x->parent);
				}
				*/
				if ((s != NULL&&s->color == BLACK) || s == NULL)
				{
					if (x == x->parent->leftChild)
					{
						x = x->parent;
						RotateR(x);
					}
					
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					RotateL(x->parent->parent);
				}
#if 0
				else if (x == x->parent->rightChild&&s != NULL&&s->color == RED)
				{
					x->color = BLACK;
					RotateL(x->parent->parent);
					if (x->parent->parent != NULL&&x->parent->parent->color == RED)
					{
						x = x->parent;
						continue;
					}
				}
				else if (x == x->parent->leftChild&&s != NULL&&s->color == RED)
				{
					x->parent->color= BLACK;
					RotateR(x->parent);
					RotateL(x->parent);
					if (x->parent != NULL&&x->parent->color == RED)
					{
						continue;
					}
				}
#endif			
				
				else if (s != NULL&&s->color == RED)
				{
					x->parent->color = BLACK;
					x->parent->parent->color = RED;
					s->color = BLACK;
					x = x->parent->parent;
					continue;
				}

				break;
			}

		}
		t->color = BLACK;
		
	}

protected:

	void RotateR(RBNode<Type>*ptr)
	{
		RBNode<Type>*subR = ptr;
		ptr = subR->leftChild;

		if (ptr->rightChild != NULL)
			ptr->rightChild->parent = subR;
		ptr->parent = subR->parent;

		if (subR->parent == NULL)
			root = ptr;
		else
		{
			if (subR == subR->parent->leftChild)
				subR->parent->leftChild = ptr;
			else
				subR->parent->rightChild = ptr;
		}
		subR->leftChild = ptr->rightChild;
		ptr->rightChild = subR;
		subR->parent = ptr;
	}
	void RotateL(RBNode<Type>*ptr)
	{
		RBNode<Type>*subL = ptr;
		ptr = subL->rightChild;

		if (ptr->leftChild != NULL)
			ptr->leftChild->parent = subL;
		ptr->parent = subL->parent;
		if (subL->parent == NULL)
		{
			root = ptr;
		}
		else
		{
			if (subL == subL->parent->leftChild)
				subL->parent->leftChild = ptr;
			else
				subL->parent->rightChild = ptr;
		}
		subL->rightChild = ptr->leftChild;
		ptr->leftChild = subL;
		subL->parent = ptr;
	}
private:
	RBNode<Type>*root;
};

void main()
{
	//int ar[] = { 16,3,1,7,11,9,26,18,14,15 };
	int ar[] = { 16,3,1,7,11,9,26,18,14,13 };

	int n = sizeof(ar) / sizeof(int);
	RBTree<int> rb;

	for (int i = 0; i < n; ++i)
	{
		rb.Insert(ar[i]);
	}
	rb.sort();
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值