您的位置:首页 > 其它

红黑树算法的思想与实现(一)

2015-06-05 13:53 183 查看
红黑树 是一颗二叉搜索树:树中每一个节点不是黑色就是红色。可以把一颗红黑树视为一颗扩充二叉树,用外部节点表示空指针。。。

有如下特性:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: