码迷,mamicode.com
首页 > 编程语言 > 详细

红黑树C语言实现--源于算法导论

时间:2016-05-13 02:57:57      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

一、概念

红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是RED或BLACK。通过对任何一条从根到叶子的简单路径上各个结点的颜色进行约束,红黑树确保没有一条路径会比其他路径长2倍,因而是近似于平衡的。

二、定义

一棵红黑树是满足下面红黑性质的二叉搜索树

1、每个结点或是红色,或是黑色;

2、根节点是黑色的;

3、每个叶节点(NIL)是黑色的;

4、如果一个结点是红色的,则它的两个子结点都是黑色的;

5、对每个结点,从该结点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点(此黑色结点的数目称为黑高)。

三、和平衡二叉树的区别

平衡二叉树是完全平衡的,而红黑树是局部平衡的,能确保没有一条路径会比其他路径长2倍,并且调整少,性能高,所以得到广泛应用,在STL里map和set都由红黑树实现。

四、节点定义

enum node_color{RED,BLACK};
typedef struct RBnode
{
    int key;//数据信息
    struct RBnode *left;//左孩子
    struct RBnode *right;//右孩子
    struct RBnode *p;//父节点
    enum node_color color;//结点颜色
}
五、示例(图中所有空指针指向叶结点NIL)

技术分享

六、旋转

目的:对红黑树进行插入和删除,可能会导致该树不在满足红黑树的性质,为了维护红黑树的性质,必须要改变树中某些结点的颜色以及指针结构。改变指针结构即通过旋转来完成,这是一种能保持二叉搜索树性质的搜索树局部操作。

1、左旋(LEFT_ROTATE)

图示:由三部完成该操作。

技术分享


代码:

//将结点x左旋
RBnode *LEFT_ROTATE(RBnode *T, RBnode *x)
{
    RBnode *y;
    
    y=x->right;//set y
    
    //step1:tunrn y's left subtree into x's right subtree
    x->right=y->left;
    if(y->left!=NIL)
        y->left->p=x;
    
    //step2:link x's parent to y
    y->p=x->p;
    if(x->p==NIL)
        T=y;
    else if(x==x->p->left)
        x->p->left=y;
    else
        x->p->right=y;
        
    //step3:put x on y's left
    y->left=x;
    x->p=y;
    
    return T;
}


2、右旋(LEFT_ROTATE)
图示:由三部完成该操作。

技术分享

代码:

//将结点x右旋
RBnode *RIGHT_ROTATE(RBnode *T, RBnode *x)
{
    RBnode *y;
    
    y=x->p;//set y
    
    //step1:tunrn x's right subtree into y's left subtree
    y->left=x->right;
    if(x->right!=NIL)
       x->right->p=y;
    
    //step2:link y's parent to x
    x->p=y->p;
    if(y->p==NIL)
        T=x;
    else if(y==y->p->left)
        y->p->left=x;
    else
        y->p->right=x;
        
    //step3:put y on x's right
    x->right=y;
    y->p=x;
    
    return T;
}

七、插入

插入操作与上一篇博文二叉排序树插入操作基本相同,除了细节之处稍有改变。

代码:

//在红黑树T上插入结点z
RBnode *RB_INSERT(RBnode *T, RBnode *z)
{
    RBnode *x;
    RBnode *y;
    
    y=NIL;
    x=T;
    while(x!=NIL)
    {
        y=x;
        if(z->key < x->key)
            x=x->left;
        else
            x=x->right;
    }
    z.p=y;
    if(y==NIL)
        T=z;
    else if(z->key < y->key)
        y->left=z;
    else
        y->right=z;
    z->left=NIL;
    z->right=NIL;
    z->color=RED;
    RB_INSERT_FIXUP(T,z);
}
八、染色和调整

由于插入操作可能破坏红黑树性质,通过RB_INSERT_FIXUP(T,z)函数调整结点颜色和树的结构,使其保持红黑性质。——明晚继续完善

红黑树C语言实现--源于算法导论

标签:

原文地址:http://blog.csdn.net/xiaowang627/article/details/51339959

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!