Browse Source

moved tree macros to trbase library, as they are also used in the memory management. Some small fixes

1.0.0
Georg Hopp 12 years ago
parent
commit
eacc711dbf
  1. 97
      include/tr/tree.h
  2. 5
      src/tree/find.c

97
include/tr/tree.h

@ -23,104 +23,9 @@
#ifndef __TR_TREE_H__
#define __TR_TREE_H__
#include "tr/tree_macros.h"
#include "trbase.h"
#define TR_TREE_RIGHT(node) (NULL!=(node)?(node)->right:NULL)
#define TR_TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL)
#define TR_TREE_PARENT(node) (NULL!=(node)?(node)->parent:NULL)
/*
* Find data in a tree.
* Attention: This will change node, so normally you need to copy
* it before using this macro.
* Also be aware that found needs to be a valid lvalue and an integer.
*/
#define TR_TREE_FIND(node, search, found, comp) \
(found) = -1; \
while((node) && ((node)->left || (node)->right)) { \
(found) = (comp)((node)->data, (search)); \
if (0 != (found)) { \
if (0 < (found)) { \
(node) = (node)->left; \
} else { \
(node) = (node)->right; \
} \
} else { \
break; \
} \
}
#define TR_TREE_CHILD(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_UNCLE(node) \
((node)->parent == (node)->parent->parent->left? \
(node)->parent->parent->right: \
(node)->parent->parent->left)
#define TR_TREE_REPLACE_NODE(root, node1, node2) \
if (NULL != (node1)->parent) { \
if ((node1) == (node1)->parent->left) { \
(node1)->parent->left = (node2); \
} else { \
(node1)->parent->right = (node2); \
} \
} else { \
*(root) = (node2); \
} \
if (NULL != (node2)) { \
(node2)->parent = (node1)->parent; \
}
#define TR_TREE_ROT_RCLD_right(node) ((node)->left)
#define TR_TREE_ROT_RCLD_left(node) ((node)->right)
#define TR_TREE_ROTATE(lr, root, node) \
if (NULL != (node)) { \
void * stPar = node->parent; \
void * relCld = TR_TREE_ROT_RCLD_##lr(node); \
void * relCCld = TR_TREE_ROT_RCLD_##lr(node)->lr; \
void * nLeft_p = &TR_TREE_ROT_RCLD_##lr(node); \
if (NULL != relCCld) { \
TR_TREE_ROT_RCLD_##lr(node)->lr->parent = node; \
} \
TR_TREE_ROT_RCLD_##lr(node)->lr = node; \
if (NULL != node->parent) { \
if (node->parent->left == node) { \
node->parent->left = relCld; \
} else { \
node->parent->right = relCld; \
} \
} else { \
*(root) = relCld; \
} \
node->parent = relCld; \
TR_TREE_ROT_RCLD_##lr(node)->parent = stPar; \
*(void**)nLeft_p = relCCld; \
}
typedef enum {rbBlack=1, rbRed=2} TR_rbColor;
#define TR_TREE_NODE_BLACK(node) (NULL == (node) || rbBlack == (node)->color)
#define TR_TREE_NODE_RED(node) (NULL == (node) || rbRed == (node)->color)
#define TR_TREE_NODE_STRICT_BLACK(node) (NULL != (node) && rbBlack == (node)->color)
#define TR_TREE_NODE_STRICT_RED(node) (NULL != (node) && rbRed == (node)->color)
#define TR_TREE_INORDER_SUCC(node, succ) \
succ = (node)->right; \
while (NULL != succ->left) { \
succ = succ->left; \
}
TR_CLASS(TR_Tree) {
void * data;

5
src/tree/find.c

@ -25,12 +25,11 @@
void *
TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
{
TR_Tree node = this;
int found;
TR_TREE_FIND(node, search, found, comp);
TR_TREE_FIND(this, search, found, comp);
return found == 0 ? node->data : NULL;
return found == 0 ? this->data : NULL;
}
// vim: set ts=4 sw=4:
Loading…
Cancel
Save