|
|
@ -32,14 +32,12 @@ |
|
|
#define TR_TREE_CHILD(node) \ |
|
|
#define TR_TREE_CHILD(node) \ |
|
|
(NULL==TR_TREE_RIGHT((node))?TR_TREE_LEFT((node)):TR_TREE_RIGHT((node))) |
|
|
(NULL==TR_TREE_RIGHT((node))?TR_TREE_LEFT((node)):TR_TREE_RIGHT((node))) |
|
|
|
|
|
|
|
|
#define TR_TREE_SIBLING(node) \ |
|
|
|
|
|
(NULL!=TR_TREE_PARENT((node))? \ |
|
|
|
|
|
((node)==TR_TREE_PARENT((node))->left? \ |
|
|
|
|
|
TR_TREE_PARENT((node))->right: \ |
|
|
|
|
|
TR_TREE_PARENT((node))->left): \ |
|
|
|
|
|
NULL) |
|
|
|
|
|
|
|
|
|
|
|
#define TR_TREE_GRANDPARENT(node) (TR_TREE_PARENT((node))->parent) |
|
|
|
|
|
|
|
|
#define TR_TREE_SIBLING(node) \ |
|
|
|
|
|
(NULL!=(node)->parent? \ |
|
|
|
|
|
((node)==(node)->parent->left? \ |
|
|
|
|
|
(node)->parent->right: \ |
|
|
|
|
|
(node)->parent->left): \ |
|
|
|
|
|
NULL) |
|
|
|
|
|
|
|
|
#define TR_TREE_UNCLE(node) \ |
|
|
#define TR_TREE_UNCLE(node) \ |
|
|
((node)->parent == (node)->parent->parent->left \ |
|
|
((node)->parent == (node)->parent->parent->left \ |
|
|
@ -110,31 +108,31 @@ typedef enum {rbBlack=1, rbRed=2} TR_rbColor; |
|
|
* it before using this macro. |
|
|
* it before using this macro. |
|
|
* Also be aware that found needs to be a valid lvalue and an integer. |
|
|
* Also be aware that found needs to be a valid lvalue and an integer. |
|
|
*/ |
|
|
*/ |
|
|
#define TR_TREE_FIND(node, search, found, comp) \ |
|
|
|
|
|
(found) = -1; \ |
|
|
|
|
|
if ((node)) { \ |
|
|
|
|
|
while(1) { \ |
|
|
|
|
|
(found) = (comp)((node)->data, (search)); \ |
|
|
|
|
|
if (0 != (found)) { \ |
|
|
|
|
|
if (0 < (found)) { \ |
|
|
|
|
|
if (! (node)->left) break; \ |
|
|
|
|
|
(node) = (node)->left; \ |
|
|
|
|
|
} else { \ |
|
|
|
|
|
if (! (node)->right) break; \ |
|
|
|
|
|
(node) = (node)->right; \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} else { \ |
|
|
|
|
|
break; \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} \ |
|
|
|
|
|
|
|
|
#define TR_TREE_FIND(node, search, found, comp) \ |
|
|
|
|
|
(found) = -1; \ |
|
|
|
|
|
if ((node)) { \ |
|
|
|
|
|
while (1) { \ |
|
|
|
|
|
(found) = (comp)((node)->data, (search)); \ |
|
|
|
|
|
if (0 != (found)) { \ |
|
|
|
|
|
if (0 < (found)) { \ |
|
|
|
|
|
if (! (node)->left) break; \ |
|
|
|
|
|
(node) = (node)->left; \ |
|
|
|
|
|
} else { \ |
|
|
|
|
|
if (! (node)->right) break; \ |
|
|
|
|
|
(node) = (node)->right; \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} else { \ |
|
|
|
|
|
break; \ |
|
|
|
|
|
} \ |
|
|
|
|
|
} \ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define TR_TREE_BALANCE_DELETE_CASE1(node) \ |
|
|
#define TR_TREE_BALANCE_DELETE_CASE1(node) \ |
|
|
if (NULL == TR_TREE_PARENT((node))) { \ |
|
|
|
|
|
break; \ |
|
|
|
|
|
|
|
|
if (NULL == (node)->parent) { \ |
|
|
|
|
|
break; \ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define TR_TREE_BALANCE_DELETE_CASE2(root, node, sibling) \ |
|
|
|
|
|
|
|
|
#define TR_TREE_BALANCE_DELETE_CASE2(root, node, sibling) \ |
|
|
if (NULL != (sibling) && rbRed == (sibling)->color) { \ |
|
|
if (NULL != (sibling) && rbRed == (sibling)->color) { \ |
|
|
(node)->parent->color = rbRed; \ |
|
|
(node)->parent->color = rbRed; \ |
|
|
(sibling)->color = rbBlack; \ |
|
|
(sibling)->color = rbBlack; \ |
|
|
@ -216,6 +214,7 @@ typedef enum {rbBlack=1, rbRed=2} TR_rbColor; |
|
|
#define TR_TREE_BALANCE_DELETE(root, node, sibling) \ |
|
|
#define TR_TREE_BALANCE_DELETE(root, node, sibling) \ |
|
|
while(1) { \ |
|
|
while(1) { \ |
|
|
TR_TREE_BALANCE_DELETE_CASE1((node)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE1((node)) \ |
|
|
|
|
|
sibling = TR_TREE_SIBLING(node); \ |
|
|
TR_TREE_BALANCE_DELETE_CASE2((root), (node), (sibling)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE2((root), (node), (sibling)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE34((root), (node), (sibling)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE34((root), (node), (sibling)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE5((root), (node), (sibling)) \ |
|
|
TR_TREE_BALANCE_DELETE_CASE5((root), (node), (sibling)) \ |
|
|
@ -224,7 +223,7 @@ typedef enum {rbBlack=1, rbRed=2} TR_rbColor; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define TR_TREE_BALANCE_INSERT_CASE1(node) \ |
|
|
#define TR_TREE_BALANCE_INSERT_CASE1(node) \ |
|
|
if (NULL == TR_TREE_PARENT((node))) { \ |
|
|
|
|
|
|
|
|
if (NULL == (node)->parent) { \ |
|
|
(node)->color = rbBlack; \ |
|
|
(node)->color = rbBlack; \ |
|
|
break; \ |
|
|
break; \ |
|
|
} |
|
|
} |
|
|
|