几点说明:
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简单的测试:#include #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#include #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