红黑树实现

来源:互联网 发布:淘宝卖原单 编辑:程序博客网 时间:2024/05/29 16:05

几点说明:

1、网上给出的一些红黑树实现示例固定了节点类型,关键字,不适合很多应用场景

2、网上给出的一些红黑树实现不能兼容节点属于多个红黑树

3、函数、变量、类型等命名不符合一般的linux风格,但有一定的原则(公司习惯遗留下来)

4、接口尽量正交、易用、最小化,不提供没有必要支持的功能,如一棵树中的节点个数(这个由使用者自己统计)

5、添加接口:只需要设置好关键字就可以正常添加,返回值非空时,表示等值的节点已经在树中,返回值是该节点的地址

6、移除接口:需要先查找,再删除,很多情况下是通过其他的途径得到节点,然后从树中删除,所以,查找和移除是分开的

7、getNext, getPrev的第二个参数指定不在树中的暂时没有实现,有需要的自己补充实现

 

头文件如下:

#ifndef __YUDS_RBTREE_H__#define __YUDS_RBTREE_H__typedef struct tag_rb_node{    unsigned long ulRbParentColor;     struct tag_rb_node *pstLeft, *pstRight;}YUDS_RBTREE_NODE_S;typedef int (*YUDS_RBTREE_CMP_FUNC)(YUDS_RBTREE_NODE_S *pstNodeInTree, YUDS_RBTREE_NODE_S *pstNode);typedef struct tag_rb_root {YUDS_RBTREE_NODE_S *pstRootNode;YUDS_RBTREE_CMP_FUNC pfnCmp;}YUDS_RBTREE_ROOT_S;#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) ({ \const typeof( ((type *)0)->member ) *__mptr = (ptr); \(type *)( (char *)__mptr - offsetof(type,member));})#define YUDS_RBTREE_ENTRY(ptr, type, member) container_of(ptr, type, member)int YuDS_rbtree_add(YUDS_RBTREE_ROOT_S *pstRoot,                     YUDS_RBTREE_NODE_S *pstNode,                     YUDS_RBTREE_NODE_S **ppstRet);void YuDS_rbtree_del(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_NODE_S *pstNode);YUDS_RBTREE_NODE_S *YuDS_rbtree_search(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_NODE_S *pstNode);YUDS_RBTREE_NODE_S *YuDS_rbtree_getFirst(YUDS_RBTREE_ROOT_S *pstRoot);YUDS_RBTREE_NODE_S *YuDS_rbtree_getLast(YUDS_RBTREE_ROOT_S *pstRoot);YUDS_RBTREE_NODE_S *YuDS_rbtree_getNext(YUDS_RBTREE_NODE_S *pstNode, int iIsNodeInTree);YUDS_RBTREE_NODE_S *YuDS_rbtree_getPrev(YUDS_RBTREE_NODE_S *pstNode, int iIsNodeInTree);void YuDS_rbtree_init(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_CMP_FUNC pfnCmp);#endif

 

实现文件如下:

#include <stdlib.h>#include <assert.h>#include "YuDS_rbtree.h"typedef enum rbtree_color{    RBTREE_COLOR_RED = 0,    RBTREE_COLOR_BLACK = 1}RBTREE_COLOR_E;#define YUDS_RBTREE_EMPTY_NODE(node) ((node)->ulRbParentColor == (unsigned long)(node))#define YUDS_RBTREE_CLEAR_NODE(node) ((node)->ulRbParentColor = (unsigned long)(node))#define RBTREE_NODE_COLOR(node) (((node)->ulRbParentColor) & 1)#define RBTREE_NODE_PARENT(node) ((YUDS_RBTREE_NODE_S *)((node)->ulRbParentColor & ~1))#define RBTREE_SET_PARENT(node, parent) \    (node)->ulRbParentColor = (unsigned long)(parent) | RBTREE_NODE_COLOR(node)#define RBTREE_SET_BLACK(node) \    (node)->ulRbParentColor |= RBTREE_COLOR_BLACK#define RBTREE_SET_PARENT_AND_COLOR(node, parent, color) \    (node)->ulRbParentColor = (unsigned long)(parent) | (color)static YUDS_RBTREE_NODE_S *rbtree_preSearch(YUDS_RBTREE_ROOT_S *pstRoot,                                             YUDS_RBTREE_NODE_S *pstNode,                                             YUDS_RBTREE_NODE_S **ppstParent,                                             YUDS_RBTREE_NODE_S ***pppstSave){    int iCmpRet = 0;    YUDS_RBTREE_NODE_S *pstNodeTmp = pstRoot->pstRootNode;    YUDS_RBTREE_NODE_S *pstParent = NULL;    YUDS_RBTREE_CMP_FUNC pfnCmp = pstRoot->pfnCmp;        while (NULL != pstNodeTmp) {        pstParent = pstNodeTmp;        iCmpRet = pfnCmp(pstNodeTmp, pstNode);        if (iCmpRet > 0)            pstNodeTmp = pstNodeTmp->pstLeft;        else if (iCmpRet < 0)            pstNodeTmp = pstNodeTmp->pstRight;        else             return pstNodeTmp;    }    if (NULL != ppstParent)         *ppstParent = pstParent;    if (NULL != pppstSave) {        if (NULL == pstParent)            *pppstSave = &pstRoot->pstRootNode;        else {            if (iCmpRet > 0)                *pppstSave = &pstParent->pstLeft;            else                *pppstSave = &pstParent->pstRight;        }    }    return NULL;}int YuDS_rbtree_add(YUDS_RBTREE_ROOT_S *pstRoot,                     YUDS_RBTREE_NODE_S *pstNode,                     YUDS_RBTREE_NODE_S **ppstRet){    YUDS_RBTREE_NODE_S *pstParent, **ppstSave, *pstGParentTmp, *pstNodeTmp;        pstNodeTmp = rbtree_preSearch(pstRoot, pstNode, &pstParent, &ppstSave);    if (NULL != pstNodeTmp) {        if (NULL != ppstRet) {            *ppstRet = pstNodeTmp;        }        return -1;    }        YUDS_RBTREE_CLEAR_NODE(pstNode);    pstNode->ulRbParentColor = (unsigned long)pstParent;     pstNode->pstLeft = pstNode->pstRight = NULL;    *ppstSave = pstNode;    while (1) {        if (NULL == pstParent) {            RBTREE_SET_PARENT_AND_COLOR(pstNode, NULL, RBTREE_COLOR_BLACK);            pstRoot->pstRootNode = pstNode;            break;        }         else if (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstParent))            break;        pstGParentTmp = RBTREE_NODE_PARENT(pstParent);        pstNodeTmp = pstGParentTmp->pstRight;        if (pstParent != pstNodeTmp) {            if ((NULL != pstNodeTmp) && (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstNodeTmp))) {                RBTREE_SET_PARENT_AND_COLOR(pstParent, pstGParentTmp, RBTREE_COLOR_BLACK);                RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstGParentTmp, RBTREE_COLOR_BLACK);                pstNode = pstGParentTmp;                pstParent = RBTREE_NODE_PARENT(pstNode);                RBTREE_SET_PARENT_AND_COLOR(pstNode, pstParent, RBTREE_COLOR_RED);                continue;            }             else {                pstNodeTmp = pstParent->pstRight;                if (pstNode == pstNodeTmp) {        pstParent->pstRight = pstNodeTmp = pstNode->pstLeft;                    pstNode->pstLeft = pstParent;                    if (NULL != pstNodeTmp)                        RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstParent, RBTREE_COLOR_BLACK);                    RBTREE_SET_PARENT_AND_COLOR(pstParent, pstNode, RBTREE_COLOR_RED);                    pstParent = pstNode;                    pstNodeTmp = pstNode->pstRight;                }                pstGParentTmp->pstLeft = pstNodeTmp;                pstParent->pstRight = pstGParentTmp;                if (NULL != pstNodeTmp)                    RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstGParentTmp, RBTREE_COLOR_BLACK);                pstNodeTmp = RBTREE_NODE_PARENT(pstGParentTmp);                pstParent->ulRbParentColor = pstGParentTmp->ulRbParentColor;                RBTREE_SET_PARENT_AND_COLOR(pstGParentTmp, pstParent, RBTREE_COLOR_RED);                if (NULL == pstNodeTmp)                    pstRoot->pstRootNode = pstParent;                else {                    if (pstNodeTmp->pstLeft == pstGParentTmp)                        pstNodeTmp->pstLeft = pstParent;                    else                         pstNodeTmp->pstRight = pstParent;                }                break;            }        }         else {            pstNodeTmp = pstGParentTmp->pstLeft;            if ((NULL != pstNodeTmp) && (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstNodeTmp))) {                RBTREE_SET_PARENT_AND_COLOR(pstParent, pstGParentTmp, RBTREE_COLOR_BLACK);                RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstGParentTmp, RBTREE_COLOR_BLACK);                pstNode = pstGParentTmp;                pstParent = RBTREE_NODE_PARENT(pstNode);                RBTREE_SET_PARENT_AND_COLOR(pstNode, pstParent, RBTREE_COLOR_RED);                continue;            }              else {                pstNodeTmp = pstParent->pstLeft;                if (pstNode == pstNodeTmp) {                    pstParent->pstLeft = pstNodeTmp = pstNode->pstRight;                    pstNode->pstRight = pstParent;                    if (NULL != pstNodeTmp)                        RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstParent, RBTREE_COLOR_BLACK);                    RBTREE_SET_PARENT_AND_COLOR(pstParent, pstNode, RBTREE_COLOR_RED);                    pstParent = pstNode;                    pstNodeTmp = pstNode->pstLeft;                }                pstGParentTmp->pstRight = pstNodeTmp;                pstParent->pstLeft = pstGParentTmp;                if (NULL != pstNodeTmp)                    RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp, pstGParentTmp, RBTREE_COLOR_BLACK);                pstNodeTmp = RBTREE_NODE_PARENT(pstGParentTmp);                pstParent->ulRbParentColor = pstGParentTmp->ulRbParentColor;                RBTREE_SET_PARENT_AND_COLOR(pstGParentTmp, pstParent, RBTREE_COLOR_RED);                if (NULL == pstNodeTmp)                    pstRoot->pstRootNode = pstParent;                else {                    if (pstNodeTmp->pstLeft == pstGParentTmp)                        pstNodeTmp->pstLeft = pstParent;                    else                        pstNodeTmp->pstRight = pstParent;                }                break;            }                    }    }    return 0;}void YuDS_rbtree_del(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_NODE_S *pstNode){    YUDS_RBTREE_NODE_S *pstNodeChild = pstNode->pstRight;    YUDS_RBTREE_NODE_S *pstNodeTmp = pstNode->pstLeft;    YUDS_RBTREE_NODE_S *pstParent, *pstSuccessor, *pstNodeChild2, *pstRebalance;    YUDS_RBTREE_NODE_S *pstSibling, *pstNodeTmp1, *pstNodeTmp2; // 这几个变量专用于调整颜色    // 如果没有左孩子    if (NULL == pstNodeTmp) {        pstParent = RBTREE_NODE_PARENT(pstNode);        if (NULL == pstParent)            pstRoot->pstRootNode = pstNodeChild;        else {            if (pstNode == pstParent->pstLeft)                pstParent->pstLeft = pstNodeChild;            else                pstParent->pstRight = pstNodeChild;        }        // 如果没有右孩子        if (NULL == pstNodeChild) {            if (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstNode))                return;            else {                if (NULL == pstParent)                    return;                pstRebalance = pstParent;                goto flag_rebalance;            }        }        // 如果有右孩子, 根据性质所有叶节点等黑高知其一定是红色        else {                                  pstNodeChild->ulRbParentColor = pstNode->ulRbParentColor;            return;            }    }    // 没有右孩子,有左孩子. 两个孩子都没有的在上一个if那里处理完了    else if (NULL == pstNodeChild) {        pstParent = RBTREE_NODE_PARENT(pstNode);        if (NULL == pstParent)            pstRoot->pstRootNode = pstNodeTmp;        else {            if (pstNode == pstParent->pstLeft)                pstParent->pstLeft = pstNodeTmp;            else                pstParent->pstRight = pstNodeTmp;        }        pstNodeTmp->ulRbParentColor = pstNode->ulRbParentColor;        return;        }    // 两个孩子都存在    else {        pstSuccessor = pstNodeChild;        pstNodeTmp = pstNodeChild->pstLeft;        if (NULL == pstNodeTmp) {            pstParent = pstSuccessor;            pstNodeChild2 = pstSuccessor->pstRight;        }        else {            do {                pstParent = pstSuccessor;                pstSuccessor = pstNodeTmp;                pstNodeTmp = pstNodeTmp->pstLeft;            } while (NULL != pstNodeTmp);            pstParent->pstLeft = pstNodeChild2 = pstSuccessor->pstRight;            pstSuccessor->pstRight = pstNodeChild;            RBTREE_SET_PARENT(pstNodeChild, pstSuccessor);        }        pstSuccessor->pstLeft = pstNodeTmp = pstNode->pstLeft;        RBTREE_SET_PARENT(pstNodeTmp, pstSuccessor);        pstNodeTmp =  RBTREE_NODE_PARENT(pstNode);        if (NULL == pstNodeTmp)             pstRoot->pstRootNode = pstSuccessor;        else {            if (pstNodeTmp->pstLeft == pstNode)                 pstNodeTmp->pstLeft = pstSuccessor;            else                 pstNodeTmp->pstRight = pstSuccessor;        }        if (NULL != pstNodeChild2) {            pstSuccessor->ulRbParentColor = pstNode->ulRbParentColor;            RBTREE_SET_PARENT_AND_COLOR(pstNodeChild2, pstParent, RBTREE_COLOR_BLACK);            return;        }        else {            if (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstSuccessor)) {                pstSuccessor->ulRbParentColor = pstNode->ulRbParentColor;                pstRebalance = pstParent;                goto flag_rebalance;            }            else {                pstSuccessor->ulRbParentColor = pstNode->ulRbParentColor;                return;    }        }    }flag_rebalance:    assert(NULL != pstRebalance);    pstParent = pstRebalance;    pstNode = NULL;    while (1) {        pstSibling = pstParent->pstRight;        // node为NULL或是左        if (pstNode != pstSibling) {            // 红兄弟 --> 转换成黑兄弟            if (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstSibling)) {                pstParent->pstRight = pstNodeTmp1 = pstSibling->pstLeft;                pstSibling->pstLeft = pstParent;                RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstParent, RBTREE_COLOR_BLACK);                pstNodeTmp = RBTREE_NODE_PARENT(pstParent);                pstSibling->ulRbParentColor = pstParent->ulRbParentColor;                RBTREE_SET_PARENT_AND_COLOR(pstParent, pstSibling, RBTREE_COLOR_RED);                if (NULL == pstNodeTmp)                    pstRoot->pstRootNode = pstSibling;                else {                    if (pstNodeTmp->pstLeft == pstParent)                        pstNodeTmp->pstLeft = pstSibling;                    else                        pstNodeTmp->pstRight = pstSibling;                }                pstSibling = pstNodeTmp1;            }                        //******************************** 黑兄弟的情况 *************************************            pstNodeTmp1 = pstSibling->pstRight;            // 1. 右侄子为空或者黑            if ((NULL == pstNodeTmp1) || (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstNodeTmp1))) {                pstNodeTmp2 = pstSibling->pstLeft;                // 左侄子为空或者黑  ---> #### 把问题上推给父亲 ###                if ((NULL == pstNodeTmp2) || (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstNodeTmp2))) {                    RBTREE_SET_PARENT_AND_COLOR(pstSibling, pstParent, RBTREE_COLOR_RED);                    if (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstParent))                        RBTREE_SET_BLACK(pstParent);                    else {                        pstNode = pstParent;                        pstParent = RBTREE_NODE_PARENT(pstNode);                        if (NULL != pstParent)                            continue;                    }                    break;                    }                // 左侄子为红, 右侄子为黑  ---> #### 转换成右红, 还没调整完毕 ###                pstSibling->pstLeft = pstNodeTmp1 = pstNodeTmp2->pstRight;                pstNodeTmp2->pstRight = pstSibling;                pstParent->pstRight = pstNodeTmp2;                if (NULL != pstNodeTmp1)                    RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstSibling, RBTREE_COLOR_BLACK);                pstNodeTmp1 = pstSibling;                pstSibling = pstNodeTmp2;            }            // 2. 右侄子为红, 左红右黑调整后需要按照这里继续处理            pstParent->pstRight = pstNodeTmp2 = pstSibling->pstLeft;            pstSibling->pstLeft = pstParent;            RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstSibling, RBTREE_COLOR_BLACK);            if (NULL != pstNodeTmp2)                RBTREE_SET_PARENT(pstNodeTmp2, pstParent);            pstNodeTmp = RBTREE_NODE_PARENT(pstParent);            pstSibling->ulRbParentColor = pstParent->ulRbParentColor;            RBTREE_SET_PARENT_AND_COLOR(pstParent, pstSibling, RBTREE_COLOR_BLACK);            if (NULL == pstNodeTmp)                 pstRoot->pstRootNode = pstSibling;            else {                if (pstNodeTmp->pstLeft == pstParent)                    pstNodeTmp->pstLeft = pstSibling;                else                    pstNodeTmp->pstRight = pstSibling;            }            break;        }        // node是右节点        else {            pstSibling = pstParent->pstLeft;            // 红兄弟 --> 转换成黑兄弟            if (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstSibling)) {                pstParent->pstLeft = pstNodeTmp1 = pstSibling->pstRight;                pstSibling->pstRight = pstParent;                RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstParent, RBTREE_COLOR_BLACK);                pstNodeTmp = RBTREE_NODE_PARENT(pstParent);                pstSibling->ulRbParentColor = pstParent->ulRbParentColor;                RBTREE_SET_PARENT_AND_COLOR(pstParent, pstSibling, RBTREE_COLOR_RED);                if (NULL == pstNodeTmp)                    pstRoot->pstRootNode = pstSibling;                else {                    if (pstNodeTmp->pstLeft == pstParent)                        pstNodeTmp->pstLeft = pstSibling;                    else                        pstNodeTmp->pstRight = pstSibling;                }                pstSibling = pstNodeTmp1;            }            //******************************** 黑兄弟的情况 *************************************            pstNodeTmp1 = pstSibling->pstLeft;            // 1. 左侄子为空或者黑            if ((NULL == pstNodeTmp1) || (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstNodeTmp1))) {                pstNodeTmp2 = pstSibling->pstRight;                // 右侄子为空或者黑  ---> #### 把问题上推给父亲 ###                if ((NULL == pstNodeTmp2) || (RBTREE_COLOR_BLACK == RBTREE_NODE_COLOR(pstNodeTmp2))) {                    RBTREE_SET_PARENT_AND_COLOR(pstSibling, pstParent, RBTREE_COLOR_RED);                    if (RBTREE_COLOR_RED == RBTREE_NODE_COLOR(pstParent))                        RBTREE_SET_BLACK(pstParent);                    else {                        pstNode = pstParent;                        pstParent = RBTREE_NODE_PARENT(pstNode);                        if (NULL != pstParent)                            continue;                    }                    break;                    }                // 右侄子为红, 左侄子为黑  ---> #### 转换成左红, 还没调整完毕 ###                pstSibling->pstRight = pstNodeTmp1 = pstNodeTmp2->pstLeft;                pstNodeTmp2->pstLeft = pstSibling;                pstParent->pstLeft = pstNodeTmp2;                if (NULL != pstNodeTmp1)                    RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstSibling, RBTREE_COLOR_BLACK);                pstNodeTmp1 = pstSibling;                pstSibling = pstNodeTmp2;                           }            // 2. 左侄子为红, 右红左黑调整后需要按照这里继续处理            pstParent->pstLeft = pstNodeTmp2 = pstSibling->pstRight;            pstSibling->pstRight = pstParent;            RBTREE_SET_PARENT_AND_COLOR(pstNodeTmp1, pstSibling, RBTREE_COLOR_BLACK);            if (NULL != pstNodeTmp2)                RBTREE_SET_PARENT(pstNodeTmp2, pstParent);            pstNodeTmp = RBTREE_NODE_PARENT(pstParent);            pstSibling->ulRbParentColor = pstParent->ulRbParentColor;            RBTREE_SET_PARENT_AND_COLOR(pstParent, pstSibling, RBTREE_COLOR_BLACK);            if (NULL == pstNodeTmp)                 pstRoot->pstRootNode = pstSibling;            else {                if (pstNodeTmp->pstLeft == pstParent)                    pstNodeTmp->pstLeft = pstSibling;                else                    pstNodeTmp->pstRight = pstSibling;            }            break;        }    }}YUDS_RBTREE_NODE_S *YuDS_rbtree_search(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_NODE_S *pstNode){    int iCmpRet = 0;    YUDS_RBTREE_NODE_S *pstNodeTmp = pstRoot->pstRootNode;    YUDS_RBTREE_CMP_FUNC pfnCmp = pstRoot->pfnCmp;        while (NULL != pstNodeTmp) {        iCmpRet = pfnCmp(pstNodeTmp, pstNode);        if (iCmpRet > 0)            pstNodeTmp = pstNodeTmp->pstLeft;        else if (iCmpRet < 0)            pstNodeTmp = pstNodeTmp->pstRight;        else             return pstNodeTmp;    }    return NULL;}YUDS_RBTREE_NODE_S *YuDS_rbtree_getFirst(YUDS_RBTREE_ROOT_S *pstRoot){    YUDS_RBTREE_NODE_S *pstNode;    pstNode = pstRoot->pstRootNode;    if (NULL == pstNode)return NULL;    while (NULL != pstNode->pstLeft)pstNode = pstNode->pstLeft;    return pstNode;}YUDS_RBTREE_NODE_S *YuDS_rbtree_getLast(YUDS_RBTREE_ROOT_S *pstRoot){    YUDS_RBTREE_NODE_S *pstNode;    pstNode = pstRoot->pstRootNode;    if (NULL == pstNode)return NULL;    while (NULL != pstNode->pstRight)pstNode = pstNode->pstRight;    return pstNode;}YUDS_RBTREE_NODE_S *YuDS_rbtree_getNext(YUDS_RBTREE_NODE_S *pstNode, int iIsNodeInTree){    YUDS_RBTREE_NODE_S *pstParent;    if (0 == iIsNodeInTree) {    }    else {    if (NULL != pstNode->pstRight) {        pstNode = pstNode->pstRight;         while (NULL != pstNode->pstLeft)            pstNode = pstNode->pstLeft;        return pstNode;    }    while ((pstParent = RBTREE_NODE_PARENT(pstNode)) && pstNode == pstParent->pstRight)        pstNode = pstParent;    return pstParent;    }}YUDS_RBTREE_NODE_S *YuDS_rbtree_getPrev(YUDS_RBTREE_NODE_S *pstNode, int iIsNodeInTree){    YUDS_RBTREE_NODE_S *pstParent;    if (0 == iIsNodeInTree) {            }    else {    if (NULL != pstNode->pstLeft) {        pstNode = pstNode->pstLeft;         while (NULL != pstNode->pstRight)    pstNode = pstNode->pstRight;        return pstNode;    }    while ((pstParent = RBTREE_NODE_PARENT(pstNode)) && pstNode == pstParent->pstLeft)        pstNode = pstParent;    return pstParent;    }}void YuDS_rbtree_init(YUDS_RBTREE_ROOT_S *pstRoot, YUDS_RBTREE_CMP_FUNC pfnCmp){    pstRoot->pstRootNode = NULL;    pstRoot->pfnCmp = pfnCmp;}


简单的测试:

#include <stdio.h>#include <stdlib.h>#include "YuDS_rbtree.h"typedef struct my_node{    YUDS_RBTREE_NODE_S stRbtreeNode;    int val;}MY_NODE_S;static YUDS_RBTREE_ROOT_S s_stRoot;int cmp(YUDS_RBTREE_NODE_S *pstNodeInTree, YUDS_RBTREE_NODE_S *pstNode){    MY_NODE_S *pstAdd, *pstIntree;    pstIntree = YUDS_RBTREE_ENTRY(pstNodeInTree, MY_NODE_S, stRbtreeNode);    pstAdd = YUDS_RBTREE_ENTRY(pstNode, MY_NODE_S, stRbtreeNode);    return pstIntree->val - pstAdd->val;}static int s_array[] = {10, 4, 6, 19, 7, 8, 22, 11, 13, 5,                         6,  8, 9, 88, 52,30,27, 19, 63, 69,                        91, 85,76,98, 23,7, 99, 88, 2,  6};int main(){    int i, iRet;    int key;    MY_NODE_S *pstNode = NULL;    MY_NODE_S stNode;    YUDS_RBTREE_NODE_S *pstRet;        YuDS_rbtree_init(&s_stRoot, cmp);        printf("@@@ test add @@@\n");    for (i = 0; i < 30; ++i)    {        key = s_array[i];        pstNode = malloc(sizeof(MY_NODE_S));        if (NULL == pstNode)        {            printf("malloc failed.\n");            break;        }        pstNode->val = key;        iRet = YuDS_rbtree_add(&s_stRoot, &pstNode->stRbtreeNode, NULL);          if (0 != iRet)        {            printf("%d already exist.\n", key);        }    }      printf("@@@ test search @@@\n");    for (i = 0; i < 30; ++i)    {        key = s_array[i];        stNode.val = key;        pstRet = YuDS_rbtree_search(&s_stRoot, &stNode.stRbtreeNode);        if (NULL != pstRet)        {            pstNode = YUDS_RBTREE_ENTRY(pstRet, MY_NODE_S, stRbtreeNode);            printf("%d ", pstNode->val);        }    }    printf("\n");    printf("@@@ test getFirst getNext @@@\n");    for (pstRet = YuDS_rbtree_getFirst(&s_stRoot);         NULL != pstRet;         pstRet = YuDS_rbtree_getNext(pstRet, 1))    {        pstNode = YUDS_RBTREE_ENTRY(pstRet, MY_NODE_S, stRbtreeNode);        printf("%d ", pstNode->val);    }    printf("\n");        printf("@@@ test getLast getPrev @@@\n");    for (pstRet = YuDS_rbtree_getLast(&s_stRoot);         NULL != pstRet;         pstRet = YuDS_rbtree_getPrev(pstRet, 1))    if (NULL != pstRet)    {        pstNode = YUDS_RBTREE_ENTRY(pstRet, MY_NODE_S, stRbtreeNode);        printf("%d ", pstNode->val);    }    printf("\n");    for (i = 0; i < 30; ++i)    {        stNode.val = s_array[i];        pstRet = YuDS_rbtree_search(&s_stRoot, &stNode.stRbtreeNode);        if (NULL != pstRet)        {            YuDS_rbtree_del(&s_stRoot, pstRet);        }        else        {            printf("YuDS_rbtree_search failed, val is %d.\n", s_array[i]);        }    }    printf("@@@ test getFirst getNext @@@\n");    for (pstRet = YuDS_rbtree_getFirst(&s_stRoot);         NULL != pstRet;         pstRet = YuDS_rbtree_getNext(pstRet, 1))    {        pstNode = YUDS_RBTREE_ENTRY(pstRet, MY_NODE_S, stRbtreeNode);        printf("%d ", pstNode->val);    }    printf("\n");    return 0;}

执行结果如下:
@@@ test add @@@
6 already exist.
8 already exist.
19 already exist.
7 already exist.
88 already exist.
6 already exist.
@@@ test search @@@
10 4 6 19 7 8 22 11 13 5 6 8 9 88 52 30 27 19 63 69 91 85 76 98 23 7 99 88 2 6
@@@ test getFirst getNext @@@
2 4 5 6 7 8 9 10 11 13 19 22 23 27 30 52 63 69 76 85 88 91 98 99
@@@ test getLast getPrev @@@
99 98 91 88 85 76 69 63 52 30 27 23 22 19 13 11 10 9 8 7 6 5 4 2
@@@ test getFirst getNext @@@
2 9 23 27 30 52 63 69 76 85 88 91 98 99

原创粉丝点击