您的位置:首页 > 其它

算法研究--使用 红黑树 解决实际问题(理论与实践)

2014-09-23 15:27 429 查看
在查找中,虽然hash表查找非常迅速,但是随着数据的种类增多,

hash表长会变得更长,且冲突也会越来越多,那么如何能实现无论在

多大数据量的情况下,查找依然是高性能的呢?

   在1978年,Leo J.Guibas 与 Robert Sedgewick写了一篇论文中

谈到了一种较好的用于查找的数据结构----红黑树

一般来说,树是很好的一种数据结构,那用于插入,删除,查找等

都是很高效的数据树构,但问题是在很坏的情况下,操作很费时间,它的

性能得到不保证,比如二叉查找树中如果左子树与右子树相差太远,那么查找

时就很费时间。这时为了保证其有高效性,就得保证左树与右树不能差得太远,

当向树中插入时,就按一定规则调整,使其达到规则,从而使其整体与局部

查找效率得到提高。这就是红黑树的规则.

   这些规则是

在二叉查找树的基础上,

(1)节点都有颜色,要么黑色,要么红色。

(2)根结点是黑色的,叶子结点是黑色的。

(3)每条从树到叶子的路上没有二个连续的红色。即红色的子树一定是黑色

(4)各条从叶子到根的路上的黑色结点相同。

关键的是(3), (4)它使得树是局部是平衡的,并且每条路线不会太长。

   还有一个重要的点就是,为了研究方便,会在红黑树补成两个子树是完整的,

它们也有颜色,是黑色,但是没有数据,它称为nil叶子,null叶子。当搜索时

发现结点与nil叶子相 等时,则是找到了叶子了。

  另外,关于红黑树与平衡二叉树的区别,它们的区别在概念上也有,

但是在性能上也有,平衡二叉树也是在最坏的情况下有高效的,但是它

追求整体的平衡,使得调整树时,会要很长的时间复杂度,而红黑树是

局部平衡,调整时只要0(logn)颜色变量,并且调整不超过三次。

那么如何使用红黑树来解决问题呢,可以先构造红黑树

构造红黑树的办法如下:

(1)定义节点结构,

一般是 值,key, 长度,左指针,右指针,指向父的指针,颜色。

(2)插入

 插入时,先从树根开始,先校验树是不是为空节点或者nil结点,若是

则插入结点为新根,若不是,则与树比较,小于的话,往左移,大于

往右移,这里与二叉查找树类似,最后再对其颜色进行调整.所谓的调

整只有4种情况,都设计好了。

(3)查找

按照二叉查找树的样子进行查找。

例子:查找班上姓名为'xiaoming'同学的基本信息情况

 办法: 则要以姓名为关键字建立一个红黑树,建法很多,

可以以其各字母ascii和的办法作为关键字,或以某函数生成一个均可。

   然后树据关键字的值生成红黑树,再查找就可以了

部分MFC代码如下:

节点结构。

typedef struct Node

{

Coulor color;

int key;

Node *p,*left,*right;

int size;

char *name; //the description data that the node contained

}Node,*pNode;

下面的代码中,rbInsert(pNode z)为插入创建的函数,

void rbInsertFixUp(pNode z)为调整局部色彩的函数。

------------------

//RBTree.h文件如下

#ifndef RBTREE_H

#define RBTREE_H

#pragma once

#include

#include"MainFrm.h"

enum Coulor{RED,BLACK};

typedef struct Node

{

Coulor color;

int key;

Node *p,*left,*right;

int size;

char *name; //the description data that the node contained

}Node,*pNode;

extern Node Nil; //ÉÚ±ø

extern const pNode nil;

class rbTree

{

public:

pNode root;

pNode cur;

public:

rbTree(){root=cur=&Nil;};

////////////////////////////

void setName(pNode x,const char*na)

{

x->name=new char[strlen(na)+1];

strcpy(x->name,na);

}

pNode newNode(int k,const char*na="N",pNode pa=nil,pNode le=nil,pNode ri=nil)

{

pNode ne=new Node;

ne->key=k;

ne->color=RED;

ne->left=le;

ne->p=pa;

ne->right=ri;

ne->size=1;

setName(ne,na);

return ne;

}

////////////////////////////////////////

//·ÃÎÊp,left,rightµÈ

pNode &p(pNode x){return x->p;};

pNode &left(pNode x){return x->left;};

pNode &right(pNode x){return x->right;};

int &size(pNode x){return x->size;};

Coulor &color(pNode x){return x->color;};

int &key(pNode x){return x->key;};

//

const pNode P(pNode x){return x->p;};

const pNode Left(pNode x){return x->left;};

const pNode Right(pNode x){return x->right;};

const int Size(pNode x){return x->size;};

const Coulor Color(pNode x){return x->color;};

const int Key(pNode x){return x->key;};

////////////////////////////////////////

pNode successor(pNode x)

{

if(Right(x) != nil)

return minimum(Right(x));

pNode y= P(x);

while ( y!=nil && x==Right(y) )

{

x=y;

y=P(y);

}

return y;

}

//////////////////////////

pNode minimum( pNode x)

{

while (Left(x)!=nil)

x=Left(x);

return x;

}

////////////////////////////

int Bheight(pNode x)

{

pNode y=x;

int k=0;

while(y!=nil)

{

if(Color(y)==BLACK)

k++;

y=Left(y);

}

return k;

}

////////////////////////////////////////////////////////////

//×óÐýת

void lrotate(pNode x)

{

pNode y=Right(x);

//ά»¤size;

int sx=x->size;

int sy=y->size;

size(y)=sx;

size(x)=sx-size(Right(y))-1;

right(x)=Left(y);

p(Left(y))=x;

p(y)=P(x);

if(P(x)==nil)

{

root=y;

}

else if( x == Left(P(x)) )

{

left(P(y))=y;

}

else

right(P(x))=y;

left(y)=x;

p(x)=y;

}

//ÓÒÐýת

void rrotate(pNode x)

{

pNode y=Left(x);

//ά»¤size;

size(y)=Size(x);

size(x)=Size(x)-Size(Left(y))-1;

left(x)=Right(y);

p(Right(y))=x;

p(y)=P(x);

if(P(x)==nil)

{

root=y;

}

else if(x==Left(P(x)))

{

left(P(y))=y;

}

else

right(P(x))=y;

right(y)=x;

p(x)=y;

}

///////////////////////////////////////////////

//²åÈë¼°Æäµ÷Õû

//²åÈë

void rbInsert(pNode z)

{

pNode y=nil;

pNode x=root;

while(x!=nil)

{

y=x;

size(x)=Size(x)+1;

if(Key(z) < Key(x))

x=Left(x);

else

x=Right(x);

}

p(z)=y;

if(y == nil)

root=z;

else if(Key(z)

left(y)=z;

else

right(y)=z;

rbInsertFixUp(z);

}

//µ÷Õû

void rbInsertFixUp(pNode z)

{

while(Color(P(z)) == RED)

{

if( P(z) == Left(P(P(z))))

{

pNode y=Right(P(P(z)));

if(Color(y) == RED)

{

color(P(z)) = BLACK;

color(y)= BLACK;

color(P(P(z))) =RED;

z=P(P(z));

}

else

{

if(z == Right(P(z)))

{

z=P(z);

lrotate(z);

}

color(P(z))=BLACK;

color(P(P(z)))=RED;

rrotate(p(P(z)));

}

}

else

{

pNode y=Left(P(P(z)));

if(Color(y) == RED)

{

color(P(z)) = BLACK;

color(y)= BLACK;

color(P(P(z))) =RED;

z=P(P(z));

}

else

{

if(z == Left(P(z)))

{

z=P(z);

rrotate(z);

}

color(P(z))=BLACK;

color(P(P(z)))=RED;

lrotate(p(P(z)));

}

}

}

color(root)=BLACK;

}

//////////////////////////////////////////////

//ɾ³ý¼°Æäµ÷Õû

//ɾ³ý

pNode rbDelete(pNode z)

{

pNode x,y;

if(Left(z) == nil ||Right(z)==nil)

y=z;

else

y=successor(z);

if(Left(y) !=nil)

x=Left(y);

else

x=Right(y);

p(x)=P(y);

if(P(y) ==nil)

root=x;

else if(y==Left(P(y)) )

left(P(y))=x;

else

right(P(y))=x;

if(y!=z)

{

key(z)=Key(y);//

}

rbDeleteMaitainSize(y);

if(Color(y)==BLACK)

rbDeleteFixUp(x);

return y;

}

//µ÷Õû

void rbDeleteFixUp(pNode x)

{

while(x!=root && Color(x)==BLACK)

{

if(x ==Left(P(x)) )

{

pNode w=Right(P(x));

//case1

if(Color(w)==RED)

{

color(w)=BLACK;

color(P(x))=RED;

lrotate(P(x));

w=Right(P(x));

}

//case 2,3,4

if(Color(Left(w))==BLACK && Color(Right(w)) ==BLACK)

{

color(w)=RED;

x=P(x);

}

else if(Color(Right(w)) == BLACK)

{

color(Left(w))=BLACK;

color(w)=RED;

rrotate(w);

w=Right(P(x));

}

else

{

color(w)=Color(P(x));

color(P(x))=BLACK;

lrotate(P(x));

x=root;

}

}

else

{

pNode w=Left(P(x));

//case1

if(Color(w)==RED)

{

color(P(x))=RED;

rrotate(P(x));

w=Left(P(x));

}

//case 2,3,4

if(Color(Left(w))==BLACK && Color(Right(w)) ==BLACK)

{

color(w)=RED;

x=P(x);

}

else if(Color(Left(w)) == BLACK)

{

color(Right(w))=BLACK;

color(w)=RED;

lrotate(w);

w=Left(P(x));

}

else

{

color(w)=Color(P(x));

color(P(x))=BLACK;

rrotate(P(x));

x=root;

}

}

}

color(x)=BLACK;

}

/////////////////////

//ά»¤size

void rbDeleteMaitainSize(pNode x)

{

cur=P(x);

while(cur!=nil)

{

size(cur)--;

cur=P(cur);

}

}

int Rank(pNode x)

{

int r= Size(Left(x))+1;

pNode y=x;

while(y!=root)

{

if( y == Right( P(y) ) )

{

r=r+Size(Left( P(y) ) )+1;

}

y=P(y);

}

return r;

}

pNode OS_Select(pNode x,int i)

{

if(i>Size(x))

return nil;

int r=Size(Left(x))+1;

if(i==r)

return x;

else if(i

return OS_Select(Left(x),i);

else

return OS_Select(Right(x),i-r);

}

friend class CMyWnd;//ÏÔʾºìºÚÊ÷µÄͼÐνçÃæÀࣻ

};

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: