Browse Source

Created a macro for tree find to prevent duplicating this code in insert and delete.

1.0.0
Georg Hopp 12 years ago
parent
commit
07cb206931
  1. 21
      include/tr/tree.h
  2. 25
      src/tree/delete.c
  3. 21
      src/tree/find.c
  4. 62
      src/tree/insert.c
  5. 4
      trdata.h

21
include/tr/tree.h

@ -29,6 +29,27 @@
#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)))

25
src/tree/delete.c

@ -28,35 +28,16 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
{
TR_Tree node = *this;
TR_Tree del_node;
int found;
void * data;
/*
* first search for it and if its found return the data
* and we are done...
*/
while (NULL != node) {
int comparison = comp(node->data, search);
if (0 < comparison) {
node = TR_TREE_LEFT(node);
continue;
}
if (0 > comparison) {
node = TR_TREE_RIGHT(node);
continue;
}
if (0 == comparison) {
break;
}
}
TR_TREE_FIND(node, search, found, comp);
/*
* nothing was found...return NULL to indicate this.
*/
if (NULL == node) {
if (found != 0) {
return NULL;
}

21
src/tree/find.c

@ -25,25 +25,12 @@
void *
TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
{
while (NULL != this) {
int comparison = comp(this->data, search);
TR_Tree node = this;
int found;
if (0 < comparison) {
this = TR_TREE_LEFT(this);
continue;
}
TR_TREE_FIND(node, search, found, comp);
if (0 > comparison) {
this = TR_TREE_RIGHT(this);
continue;
}
if (0 == comparison) {
break;
}
}
return NULL != this ? this->data : NULL;
return found == 0 ? node->data : NULL;
}
// vim: set ts=4 sw=4:

62
src/tree/insert.c

@ -28,6 +28,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
{
TR_Tree node = *this;
TR_Tree new_node = NULL;
int found;
TR_TREE_FIND(node, search, found, comp);
/*
* insert the node or return the one in tree if comparison
@ -40,43 +43,24 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
*/
*this = node = new_node = TR_new(TR_Tree, search);
} else {
/*
* first search for it and if its found return the data
* and we are done...
*/
while (NULL != node) {
int comparison = comp(node->data, search);
if (0 < comparison) {
if (NULL != TR_TREE_LEFT(node)) {
node = TR_TREE_LEFT(node);
continue;
} else {
node->left = TR_new(TR_Tree, search);
node->left->parent = node;
node = new_node = node->left;
break;
}
}
if (0 > comparison) {
if (NULL != TR_TREE_RIGHT(node)) {
node = TR_TREE_RIGHT(node);
continue;
} else {
node->right = TR_new(TR_Tree, search);
node->right->parent = node;
node = new_node = node->right;
break;
}
}
if (0 == comparison) {
// as this is insert and not find this will overwrite an existing value,
// but return the previos one so that it can be freed if neccessary.
void * data = node->data;
node->data = (void *)search;
return data;
if (found == 0) {
// we found an element
// as this is insert and not find this will overwrite an existing
// value, but return the previous one so that it can be freed if
// neccessary.
void * data = node->data;
node->data = (void *)search;
return data;
} else {
// not found
if (0 < found) {
node->left = TR_new(TR_Tree, search);
node->left->parent = node;
node = new_node = node->left;
} else {
node->right = TR_new(TR_Tree, search);
node->right->parent = node;
node = new_node = node->right;
}
}
}
@ -114,13 +98,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
&& node->parent == node->parent->parent->left) {
TR_TREE_ROTATE(left, this, node->parent);
node = TR_TREE_LEFT(node);
node = node->left;
} else if (node == node->parent->left
&& node->parent == node->parent->parent->right) {
TR_TREE_ROTATE(right, this, node->parent);
node = TR_TREE_RIGHT(node);
node = node->right;
}

4
trdata.h

@ -11,13 +11,13 @@
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
/* #undef HAVE_MEMSET */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if stdbool.h conforms to C99. */
/* #undef HAVE_STDBOOL_H */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

Loading…
Cancel
Save