您的位置:首页 > 其它

(原创)红黑树red black tree "insert" "rotate" "search"

2010-06-29 17:41 417 查看
转载请注明出处.

红黑树的定义:
是满足下列条件的二叉搜索树.
1,每个结点要么是红色,要么是黑色.
2,所有的叶节点都是空节点,并且是黑色.
3,如果一个节点是红色的,那么它的两个子节点都是黑色的.(从每个叶子到根的所有路径上不能有两个连续的红色节点,注:也就是說,如果結點是黑色的,那么它的子節點可以是紅色或者是黑色的).
4,节点到其子孙节点的每条简单路径都包含相同的数目的黑色节点.
5,根节点永远是黑色的.
Black-height:从根节点到叶节点的黑色节点数被称为黑色高度.
红黑树并不是严格意义上的平衡二叉树,但恰恰相反,红黑树放松了平衡二叉树的某系要求,使得性能有所提高.红黑树和AVL树的区别在于它使用颜色来标识结点的高度,它所追求的是局部平衡而不是AVL树中的非常严格的平衡。
红黑树的平衡:
红黑树首先是一棵二叉查找树,它每个结点都被标上了颜色(红色或黑色),红黑树满足以下5个性质:
1、 每个结点的颜色只能是红色或黑色。
2、 根结点是黑色的。
3、 每个叶子结点都带有两个空的黑色结点(被称为黑哨兵),如果一个结点n的只有一个左孩子,那么n的右孩子是一个黑哨兵;如果结点n只有一个右孩子,那么n的左孩子是一个黑哨兵。
4、 如果一个结点是红的,则它的两个儿子都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。
5、 对于每个结点来说,从该结点到其子孙叶结点的所有路径上包含相同数目的黑结点。
红黑树的这5个性质中,第3点是比较难理解的,但它却非常有必要。我们看图1中的左边这张图,如果不使用黑哨兵,它完全满足红黑树性质,结点50到两个叶结点8和叶结点82路径上的黑色结点数都为2个。但如果加入黑哨兵后(如图1右图中的小黑圆点),叶结点的个数变为8个黑哨兵,根结点50到这8个叶结点路径上的黑高度就不一样了,所以它并不是一棵红黑树。
红黑树也是一种二叉树,那么其左边的值必须小于或等于右边的值.
红黑树的插入:
1. 红黑树的插入和普通搜索二叉树(Binary Search Tree)的插入一样,只是在插入完以后,将新插入的节点标记为红色,然后从该节点开始,向上进行调整颜色。
2. 向上调整颜色进行旋转时,旋转的原则是尽量用1次或者最多2次旋转完成,并且旋转操作不能影响该层以下层次的节点,只能影响其父节点,然后将其父节点(或者叔节点、兄弟节点)作为新的要调整颜色节点,继续向上递推调整。
3. 调整完后注意检查根的颜色是否还是黑色。
红黑树的节点删除:
红黑树节点的删除要分几种情况:
1:如果被删除节点没有子节点,那么其位置被他的父亲节点继承.若删除的是黑色节点的话,那么要影响黑色高度.
2;如果有一个节点,那么这个子孙节点继承它的位置.
3:如果有两个子孙节点,那么继承它位置的是其中序遍历中其前驱.
以上的3种情况都会涉及如果删除的是黑色的节点的话,就要调整其黑色的高度,那么也要紧接着调整其颜色,已满足,其5个性质.
下面是linux中红黑树的定义:

Struct rb_node
{
Struct rb_node *rb_parent;
int rb-color;
#define RED 0
#define BLACK 1
struct rb_node *rb_right;
struct rb_node *rb_left;
}
红黑树的实现:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef int KEY;
enum NODECOLOR
{
BLACK=0;
RED=1;
};
typedef struct RBTREE
{
struct RBTREE *parent;
struct RBTREE *left,*right;
KEY key;
NODECOLOR color;
}RBTREE,*prbtree;
//left rotate
void left_rotate(prbtree A,prbtree *root)
{
prbtree B;
A->right=B;
if(B==NULL);
return ;
A->right=B->left;
if(B->left!=NULL)
{
B->left->parent=A;
}
if(A==root)
{
root=B;
}

else if(A==A->parent->right)
{
A->parent->rifht=B;
}
B->left=A;
A->parent=B;
}
//right rotete
void right_rotate(prbtree A,prbtree *root)
{
prbtree B;
A->left=B;
if(B==NuLL)
return;
A->left=B->right;
if(B->right!=NULL)
{
B->right->parent=A;
}
if(A==root)
{
root=B;
}
else if(A==A->parent->left)
{
A->parent->left=B;
}
else if(A==A->parent->right)
{
A->parent->right=B;
}
A->parent=B;
B->right=A;
}
//find the "key" node
prbtree find_node(prbtree root,KEY key)
{
prtree x;
x=root;
do
{
if(key==x->key)
break;
if(key<x->key)
{
if(NULL!=x->key)
x=x->key;
else
break;
}
if(key>x->key)
{
if(NULL!=x->right)
x=x->right;
else
break;
}while(NULL!=x)
return x;
}
//insert the node 'key'
prbtree insert_node(prbtree root,prbtree key)
{
prbtree z,x,y;
if(NULL==(z=(prbtree)malloc(sizeof(prbtree)));
{
printf("malloc is error");
}
z->key=key;
x=root;
y=NULL:
if(x!=NULL)
{
y=x;
if(z->key<x->key)
{
if(x->key!=NULL)
x=x->left;
else
break;
}
else if(z->key>x->key)
{
if(x->key!NULL)
x=x->right;
else
break;
}
z->parent=y;
if(y==NULL)
{
root=z;
}
else if(z->key>y->key)
{
y->right=z;
}
else if(z->key<y->key)
{
y->left=z;
}
//设置插入节点的子节点为空,且insert node为红色
z->right=z->left=NULL;
z->color=RED;
//对红黑树的节点颜色进行调整

return rb_nodefixup(root,z);
}
}
//insert the node then fixup
prbtree node_insert_fixup(prbtee root,prbtree z)
{
prbtree y;
while(root!=z&&RED==z->parent->left)
{
if(z->parent==z->parent->parent->left)
{
y=z->parent->right;
if(NULL!=y&&RED==y->color)
{
z->parent->color=BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
}
else
{
if(z==z->parent->left)
{
z->parent->color=BLACK;
z->color=RED;
z->parent->parent->color=RED;
}
else
{
prbtree y=z->parent;
z->color=BLACK;
z->parent->color=RED;
z->parent->parent->color=RED;
//以z结点左单旋转
left_rotate(z,root);
//z结点右单旋转
right_rotate(y,root);
z=temp;
}
}
}
else
{
if(z->parent->parent->left&&RED=z->parent->parent->color)
{
z->parent->color=BLACK;
z->parent->parent->color=RED;
z->parent->parent->left->color=BLACK;
z=z->parent->parent;
}
else
{
if(z=z->parent->right)
{
z->parent->color=BLACK;
z->parent->parent->color=RED;
z->color=RED;
//以parent结点左单旋转
left_rotate(z,root);
z=z->parent;
}
else
{
prbtree y=z->parent;
z->color=BLACLK;
z->parent->color=RED;
z->parent->parent->color=RED;
//以结点z右单旋转
right_rotate(z,root);
//以结点z左单旋转
left_rotate(z,root);
z=y;
}
}

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