原创 红黑树算法C实现

2010-1-21 10:48 3465 5 6 分类: 软件与OS

/*******************************************************************************
文件: rbtree.h
作者: 天朝匠人
说明: 本文件是REFS文件系统应用的红黑树算法的例程,如果要正确使用本程序,需要提
       供一个哨兵NIL,另在结构体中U16和U8需要定义。哨兵节点的定义如下:
       NIL = malloc(sizeof(rbtreeNode));
       NIL->color = BLACK;
*******************************************************************************/


#include "../config/type.h"


enum color
{    BLACK,RED   };
typedef struct _rbtreeNode
{
    U16 key;
    U8  color;
    struct _rbtreeNode  *left;
    struct _rbtreeNode  *right;
    struct _rbtreeNode  *p;
} rbtreeNode;


void rbtLeftRotate(rbtreeNode **root,rbtreeNode *xNode);
void rbtRightRotate(rbtreeNode **root,rbtreeNode *xNode);


void rbtInsertFixup(rbtreeNode **root,rbtreeNode *zNode);
void rbtDeleteFixup(rbtreeNode **root, rbtreeNode *xNode);


rbtreeNode *rbtMinimum(rbtreeNode *xNode);
rbtreeNode *rbtMaximum(rbtreeNode *xNode);


rbtreeNode *rbtPredecessor(rbtreeNode *xNode);
rbtreeNode *rbtSuccessor(rbtreeNode *xNode);


void rbtInsert(rbtreeNode **root,rbtreeNode *zNode);
void rbtDelete(rbtreeNode **root, rbtreeNode *zNode);


/*******************************************************************************
文件: rbtree.c
作者: 天朝匠人
说明: 本文件是REFS文件系统应用的红黑树算法的例程,如果要正确使用本程序,需要提
       供一个哨兵NIL,另在结构体中U16和U8需要定义。哨兵节点的定义如下:
       NIL = malloc(sizeof(rbtreeNode));
       NIL->color = BLACK;
*******************************************************************************/
#include "rbtree.h"


rbtreeNode *NIL;


void rbtLeftRotate(rbtreeNode **root,rbtreeNode *xNode)
{
    rbtreeNode *yNode = xNode->right;
    xNode->right = yNode->left;
    if(yNode->left!=NIL)
    {   yNode->left->p = xNode; }
    yNode->p = xNode->p;
    if(xNode->p ==NIL)
    {   *root = yNode;   }
    else if(xNode == xNode->p->left)
    {   xNode->p->left = yNode; }
    else
    {   xNode->p->right = yNode;    }
    yNode->left = xNode;
    xNode->p = yNode;
    return;
}
void rbtRightRotate(rbtreeNode **root,rbtreeNode *xNode)
{
    rbtreeNode *yNode = xNode->left;
    xNode->left = yNode->right;
    if(yNode->right!=NIL)
    {   yNode->right->p = xNode; }
    yNode->p = xNode->p;
    if(xNode->p ==NIL)
    {   *root = yNode;   }
    else if(xNode == xNode->p->right)
    {   xNode->p->right = yNode; }
    else
    {   xNode->p->left = yNode;    }
    yNode->right = xNode;
    xNode->p = yNode;
    return;
}


void rbtInsertFixup(rbtreeNode **root,rbtreeNode *zNode)
{
    rbtreeNode *yNode;
    while((zNode!=*root)&&(zNode->p->color == RED))
    {
        if(zNode->p == zNode->p->p->left)
        {
            yNode = zNode->p->p->right;
            if(yNode->color == RED) /*  CASE 1  */
            {  
                zNode->p->color = BLACK;
                yNode->color = BLACK;
                zNode->p->p->color = RED;
                zNode = zNode->p->p;
            }
            else
            {
                if(zNode == zNode->p->right)   /*  CASE 2  */
                {
                    zNode = zNode->p;
                    rbtLeftRotate(root, zNode);
                }
                zNode->p->color = BLACK;      /*   CASE 3 */
                zNode->p->p->color = RED;
                rbtRightRotate(root, zNode->p->p);
            }
        }
        else
        {
            yNode = zNode->p->p->left;
            if(yNode->color == RED) /*  CASE 1  */
            {  
                zNode->p->color = BLACK;
                yNode->color = BLACK;
                zNode->p->p->color = RED;
                zNode = zNode->p->p;
            }
            else
            {
                if(zNode == zNode->p->left)   /*  CASE 2  */
                {
                    zNode = zNode->p;
                    rbtRightRotate(root, zNode);
                }
                zNode->p->color = BLACK;      /*   CASE 3 */
                zNode->p->p->color = RED;
                rbtLeftRotate(root, zNode->p->p);
            }
        }
    }
    (*root)->color = BLACK;
}
void rbtInsert(rbtreeNode **root,rbtreeNode *zNode)
{
    rbtreeNode *yNode = NIL;
    rbtreeNode *xNode = *root;
    while(xNode != NIL)
    {
        yNode = xNode;
        if(zNode->key < xNode->key)
        {   xNode = xNode->left;    }
        else
        {   xNode = xNode->right;   }
    }
    zNode->p = yNode;
    if(yNode == NIL)
    {   *root = zNode;   }
    else if(zNode->key < yNode->key)
    {   yNode->left = zNode;    }
    else
    {   yNode->right = zNode;   }
    zNode->left = NIL;
    zNode->right = NIL;
    zNode->color = RED;
    rbtInsertFixup(root, zNode);
   
}


rbtreeNode *rbtMinimum(rbtreeNode *xNode)
{
    while(xNode->left != NIL)
    {   xNode = xNode->left;    }
    return xNode;
}
rbtreeNode *rbtMaximum(rbtreeNode *xNode)
{
    while(xNode->right != NIL)
    {   xNode = xNode->right;    }
    return xNode;
}
rbtreeNode *rbtSuccessor(rbtreeNode *xNode)
{
    rbtreeNode *yNode;
    if(xNode->right != NIL)
    {   return rbtMinimum(xNode->right);    }
    yNode = xNode->p;
    while((yNode != NIL)&&(xNode == yNode->right))
    {
        xNode = yNode;
        yNode = xNode->p;
    }
    return yNode;
}
rbtreeNode *rbtPredecessor(rbtreeNode *xNode);
{
    rbtreeNode *yNode;
    if(xNode->left != NIL)
    {   return rbtMinimum(xNode->right);    }
    yNode = xNode->p;
    while((yNode != NIL)&&(xNode == yNode->left))
    {
        xNode = yNode;
        yNode = xNode->p;
    }
    return yNode;
}
void rbtDeleteFixup(rbtreeNode **root, rbtreeNode *xNode)
{
    rbtreeNode *wNode;
    while((xNode != *root)&&(xNode->color == BLACK))
    {
        if(xNode == xNode->p->left)
        {
            wNode = xNode->p->right;
            if(wNode->color == RED) /*  CASE 1  */
            {
                wNode->color = BLACK;
                xNode->p->color = RED;
                rbtLeftRotate(root, xNode->p);
                wNode = xNode->p->right;
            }
            if((wNode->left->color == BLACK)&&(wNode->right->color == BLACK))
            {                       /*  CASE 2  */
                wNode->color = RED;
                xNode = xNode->p;
            }
            else
            {
                if(wNode->right->color == BLACK)    /*  CASE 3  */
                {
                    wNode->left->color = BLACK;
                    wNode->color = RED;
                    rbtRightRotate(root, wNode);
                    wNode = xNode->p->right;
                }
                wNode->color = xNode->p->color; /*  CASE 4  */
                xNode->p->color = BLACK;
                wNode->right->color = BLACK;
                rbtLeftRotate(root, xNode->p);
                xNode = *root;
            }
        }
        else
        {
            wNode = xNode->p->left;
            if(wNode->color == RED) /*  CASE 1  */
            {
                wNode->color = BLACK;
                xNode->p->color = RED;
                rbtRightRotate(root, xNode->p);
                wNode = xNode->p->left;
            }
            if((wNode->right->color == BLACK)&&(wNode->left->color == BLACK))
            {                       /*  CASE 2  */
                wNode->color = RED;
                xNode = xNode->p;
            }
            else
            {
                if(wNode->left->color == BLACK) /*  CASE 3  */
                {
                    wNode->right->color = BLACK;
                    wNode->color = RED;
                    rbtLeftRotate(root, wNode);
                    wNode = xNode->p->left;
                }
                wNode->color = xNode->p->color; /*  CASE 4  */
                xNode->p->color = BLACK;
                wNode->left->color = BLACK;
                rbtRightRotate(root, xNode->p);
                xNode = *root;
            }
        }
    }
    xNode->color = BLACK;
}
void rbtDelete(rbtreeNode **root, rbtreeNode *zNode)
{
    rbtreeNode *xNode,*yNode;
    if((zNode->left==NIL)||(zNode->right==NIL))
    {   yNode = zNode;  }
    else
    {   yNode = rbtSuccessor(zNode);    }
    if(yNode->left != NIL)
    {   xNode = yNode->left;    }
    else
    {   xNode = yNode->right;   }
    xNode->p = yNode->p;
    if(yNode->p == NIL)
    {   *root =xNode;   }
    else if(yNode == yNode->p->left)
    {   yNode->p->left = xNode; }
    else
    {   yNode->p->right = xNode;    }
    if(yNode != zNode)
    {   zNode->key = yNode->key;    }
    if(yNode->color == BLACK)
    {   rbtDeleteFixup(root, xNode);   }
}

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1589211 2010-1-24 10:46

typedef unsigned char U8; typedef unsigned short U16;
相关推荐阅读
用户1589211 2011-03-10 09:29
读《设计与生存》有感:磨生命之剑
学习是研发工程师生活工作不可缺少的重要组成部分,“终身学习”是他们人生矢志不渝的信念。读完马宁伟先生的一系列文章,我深受启发:“学习,就是磨剑,磨生命之剑。” 一、磨剑前的准备工作。 拿到剑胚,我们不...
用户1589211 2011-03-09 16:50
重新拾起嵌入式
准确地说,今天才是我真正的生日,在这特殊的日子里,留下些文字,了表记忆。 来公司工作已近九月了,最终在“灰狗”大师的帮助下,才进入真正的“嵌入式”工作,而前面近七个月的时间真的太糟糕了。技术方面没有任...
用户1589211 2010-12-10 14:28
FAT文件系统试验成功了
今天终于在LPC2468平台上利用其USB读写U盘完成了我的FAT文件系统的实现代码。支持文件系统有FAT16和FAT32。支持U盘有朗科64M和4G,以及清华紫光的1G和4G,其他U盘应该也能支持,...
用户1589211 2010-06-19 17:08
【转】示波器探头的科学——示波器出现50HZ干扰
今天看到一篇关于示波器探头的文章,感觉很好,转来与E友分享。原文地址:http://hi.baidu.com/jonseen/blog/item/80663716aecee157f3de32dc.ht...
用户1589211 2010-05-07 00:14
我的第一个运放LM358
今晚调好了用LM358搭建的射极跟随器和减法电路,从示波器中看到了我想要的波形。前两天老是出现了50HZ的正弦波,让我百思不得其解,请教了路老师,他说很可能是LM358的电源没接好引起了运放的振荡,这...
用户1589211 2010-04-20 16:41
智能卡的收获
以前,花了很多精力在125KHZ低频非接触式卡的读写上,但没有稳定,这几天把以前的板子重新焊了块,终于把EM4100卡和T5557卡的通讯调好了,读卡快速准确稳定,感觉挺有收获的。唯一感到不足的是目前...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条