1. 程式人生 > >紅黑樹演算法的思想與實現(一)

紅黑樹演算法的思想與實現(一)

紅黑樹 是一顆二叉搜尋樹:樹中每一個節點不是黑色就是紅色。可以把一顆紅黑樹視為一顆擴充二叉樹,用外部節點表示空指標。。。

有如下特性:

1.根節點和所有外部節點的顏色是黑色。

2.從根節點到外部節點的途中沒有連續兩個節點的顏色是紅色。

3.所有從根節點到外部節點的路徑上都有相同數目的黑色節點。

一、紅黑樹的搜尋

對普通二叉搜尋樹進行搜尋的時間複雜度為O(h), 對於紅黑樹則為O(lg n)--《以2為底n的對數》;

最差情況下AVL樹的時間複雜度最優。

二、紅黑樹的插入

首先使用二叉搜尋樹的插入演算法將一個元素插入到紅黑樹中,在插入過程中需要為其染色。

①、如果插入前是是空樹,那麼新元素將成為根節點,根據特徵1,根節點必須染成黑色。

②、如果插入前樹非空,若新節點被染成黑色,將違反紅黑樹特性3,所有從根到外部節點的路徑上的黑色節點個數不等。因此 新插入節點將被染成紅色,但這又可能違反紅黑樹的特性2,出現連續兩個紅色節點,因此需要重新平衡。

設新插入節點為u, 它的父節點和祖父節點分別為pu,gu,

②.1 若pu是黑色節點,則特性2沒有被破壞,結束重新平衡的過程。 

pu是紅色節點,則出現連續兩個紅色節點的情形,這時考察pu的兄弟節點 

 ②.2.1pu的兄弟節點gr是紅色節點, 此時gu為黑色,它有兩個紅色節點。交換節點gu和它的兩個子女的顏色,將可能破壞紅黑樹特性2,

因此需先判斷判斷gu是否為根節點,若不是根節點,則交換gu與它的兩個子女顏色;若gu是根節點,則只需將兩個子女節點的顏色變為gu的顏色,而gu顏色無需改變。

②.2.2 pu的兄弟節點為黑色,此時又有兩種情況。

---1>pu是gu的左子女,u是pu的 左子女。  ---->交換pu和gu的顏色做一次右單旋轉

u是pu的右子女。   ---->交換u和gu的顏色,左旋轉,再右旋轉。

---2>pu是gu的右子女,u是pu右子女。    ---->交換pu和gu的顏色,做一次左單旋轉

u是pu的左子女。  ---->先交換u和gu的顏色,左旋轉,右旋轉

總歸紅黑樹插入這麼分 :1、黑父,  2、紅父, 2.1、紅叔, 2.2、黑叔。

#include<iostream>
#include<assert.h>
using namespace std;

typedef int Type;

typedef enum Color{RED,BLACK};

typedef struct RBNode
{
	Type   data;
	Color  color;
	struct RBNode *leftChild;
	struct RBNode *rightChild;
	struct RBNode *parent;	
}RBNode;

typedef struct RBTree
{
	RBNode *root;
	RBNode *nul;
	
}RBTree;

RBNode* buynode()
{
	RBNode *s = new RBNode;
	assert(s != NULL);
	memset(s,0,sizeof(RBNode));
	return s;
}

void InitRBTree(RBTree &t)
{
	t.nul = buynode();
	t.root = t.nul;
	t.nul->color = BLACK;
	t.nul->data = -1;
}

void RotateR(RBTree &t,RBNode *x) //右轉,將根節點變為x的左子樹節點
{
	RBNode *subR = x;
	x = subR->leftChild;
	subR->leftChild = x->rightChild;
	if(x->rightChild != t.nul)
		x->rightChild->parent = subR;
	x->rightChild = subR;
	if(subR->parent == t.nul)
	{
		t.root = x;
	}
	else if(subR == subR->parent->leftChild)
		subR->parent->leftChild = x;
	else
		subR->parent->rightChild = x;
	x->parent = subR->parent;
	subR->parent = x;
}
void RotateL(RBTree &t, RBNode *x) //根節點變為x的右子樹
{
	RBNode *subL = x;
	x = subL->rightChild;
	subL->rightChild = x->leftChild;
	if(x->leftChild != t.nul)
		x->leftChild->parent = subL;
	x->leftChild = subL;
	if(subL->parent == t.nul)
		t.root = x;
	else if(subL->parent->rightChild == subL)
		subL->parent->rightChild = x;
	else
		subL->parent->leftChild = x;
	x->parent = subL->parent;
	subL->parent = x;
}

void insert_rebalance(RBTree &t, RBNode *u)
{
	u->color = RED;
	RBNode *pu = u->parent;
	RBNode *gu = pu->parent;
	while(u!=t.root && pu->color==RED)
	{
		if(gu->leftChild == pu)
		{
		 
			if(gu->rightChild && gu->rightChild->color == RED) //pu的兄弟節點存在且是紅色
			{                                          //此時gu是黑色,他有兩個紅色子女節點
														//交換gu和其兩個子女的顏色
				gu->rightChild->color = BLACK;
				pu->color = BLACK;
				if(gu->data != t.root->data)
					gu->color = RED;			
			}
			else  //pu的兄弟節點顏色為黑色
			{
				if(pu->leftChild == u) //u、pu、gu都在一條左子樹上
				{//交換pu、gu的顏色
					pu->color = BLACK;
					gu->color = RED;
					RotateR(t,gu);
				}
				else
				{					
					gu->color = RED;
					u->color = BLACK;
					RotateL(t,pu);
					RotateR(t,gu);	
					return;
				}
			}
		}
		else  //gu->rightChild == pu
		{
			if(gu->leftChild && gu->leftChild->color == RED)  //交換gu和其兩個子女的顏色
			{
				gu->leftChild->color = BLACK;
				pu->color = BLACK;
				if(gu->data != t.root->data)
					gu->color = RED;						
			}
			else //pu的兄弟節點顏色為黑色
			{
				if(pu->leftChild == u)
				{
					
					gu->color = RED;
					u->color = BLACK;
					RotateR(t,pu);
					RotateL(t,gu);
					return;
				}
				else
				{
					gu->color = RED;
					pu->color = BLACK;
					RotateL(t,gu);
				}
			}
		}

	}
	t.root->color = BLACK;
	return;
}

bool Insert(RBTree &t, const Type u)
{
	RBNode *parent = t.nul;
	RBNode *p = t.root;
	while(p != t.nul)
	{
		if(t.root->data == u)
			return false;
		parent = p;
		if(parent->data < u)
			p = parent->rightChild;
		else
			p = parent->leftChild;	
	}
	p = buynode();
	p->data = u;
	p->color = RED;
	p->leftChild = t.nul;
	p->rightChild = t.nul;
	p->parent = t.nul;

	if(t.root == t.nul)
	{
		t.root = p;
		t.root->color = BLACK;
		return true;
	}
	
	if(parent->data > u)
		parent->leftChild = p;
	else
		parent->rightChild = p;
	
	p->parent = parent;
	insert_rebalance(t,p);
	return true;
}
void remove_balance(RBTree &t, RBNode *p)
{
	RBNode *u;
	RBNode *g = p->parent;
	RBNode *v = g->leftChild;
	RBNode *w = v->leftChild;
	RBNode *r = v->rightChild;
	if(p->rightChild == t.nul)  //兩種情況,1。p->leftChild!=t.nul 2.p->rightChild==t.nul
	{
		if(p->leftChild != t.nul)
		{
			u = p->leftChild;
			if(p->color == RED)
			{
				g->rightChild = u;
			}
			else
			{
				if(u->color == RED)
					u->color = BLACK;
				g->rightChild = u;		
				if(v->color == BLACK)  //v是u的左兄弟
				{
					
					if(w && w->color==RED) //v的左子女為w
					{
						w->color = BLACK;
						g->color = BLACK;
						v->color = RED;
						RotateR(t, g);				
					}
					else
					{	
						if(r && r->color == RED) //w的有兄弟節點r
						{
							g->color = BLACK;
							RotateL(t, v);
							RotateR(t, g);
						}
						else
						{
							if(g->color == RED)
							{
								g->color = BLACK;
								v->color = RED;
							}
							else
							{
								
								RotateR(t, g);
							}
						}
					}
				}
				else  //v->color = RED
				{
					RBNode* s = r->leftChild;  
					if(s->color == RED)
					{
						RotateL(t, v);
						RotateR(t, g);
					}
					else //s->color==BLACK
					{
						RBNode* q = r->rightChild;
						if(q->color == RED)
						{
							RotateL(t,r);
							RotateL(t, v);
							RotateR(t, g);
						}
						else  //q->color == BLACK
						{
							r->color = RED;
							v->color = BLACK;
							RotateR(t, v);
						}
					}
				}
			}
		}  
		else //p->leftChild == t.nul && p->rightChild==t.nul
		{
			if(p == g->leftChild)
			{
				if(p->color == BLACK)
				{
					if(g->rightChild->color == RED)
					{
						
					}
				}
				g->leftChild = t.nul;
			}	
			else
			{
				if(p->color == BLACK)
				{
					g->leftChild->color = BLACK;
					g->color = RED;
					RotateR(t, g);			
				}			
				g->rightChild = t.nul;
			}
				
		}
		//freenode(p);
		delete p;
	}
	else  //p->rightChild != t.nul  -->(p->leftChild==t.nul)
	{
		RBNode *pr=p->rightChild;
		if(p->color == RED)
		{
			if(g->rightChild == p)
				g->rightChild = pr;
			else
				g->leftChild = pr;
		}
		else //p->color==BLACK
		{
			
		}
	}

	
}
bool Remove(RBTree &t,const Type& u)
{
	RBNode *p = t.root;
	while(p != t.nul)
	{
		if(p->data == u)
		{
			RBNode *tmp;
			//調整
			if(p->leftChild != t.nul && p->rightChild != t.nul)
			{
				//RBNode* l = p->leftChild;
				tmp = p->rightChild;
				while(tmp->leftChild != t.nul)
					tmp = tmp->leftChild;
				p->data = tmp->data;
				remove_balance(t, tmp);
			}
			else  //被刪節點只有一個子女或沒有子女	
			{
				remove_balance(t, p);
			}						
			return true;
		}		
		if(p->data > u)
			p = p->leftChild;
		else
			p = p->rightChild;
	}	
	return false;
}

void visit(RBNode *t)
{
	cout<<t->data<<"("<<t->color<<")"<<"  ";
}

void Print(RBTree &t)
{
	RBNode *p = t.root;
	stack<RBNode*> st;
	while(p!=t.nul || !st.empty())
	{
		if(p!=t.nul)
		{
			st.push(p);
			p = p->leftChild;
		}
		else
		{
			p = st.top();
			st.pop();
			visit(p);
			p = p->rightChild;
		}
	}
	cout<<endl;
}

size_t size(RBTree &t)
{
	RBNode *p = t.root;
	stack<RBNode*> st;
	int count = 0;
	while(p!=t.nul || !st.empty())
	{
		if(p!=t.nul)
		{
			st.push(p);
			p = p->leftChild;
		}
		else
		{
			p = st.top();
			st.pop();
			count++;
			p = p->rightChild;
		}
	}
	//cout<<count<<endl;
	return count;
}
//main函式
#include "RBTree.h"

void main()
{
	int a[] = {10,12,3,8,11,5,20,7,18};
	RBTree rbt;
	InitRBTree(rbt);
	for(int i=0; i<(sizeof(a)/sizeof(int)); ++i)
	{
		Insert(rbt,a[i]);
	}
	Remove(rbt, 10);
	Remove(rbt, 12);
	Remove(rbt, 18);
	Print(rbt);
	cout<<size(rbt)<<endl;
}