Commit 07cb206931c6a135a0d038c7a6a06ceb5507d427

Authored by Georg Hopp
1 parent af8994b0

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

... ... @@ -29,6 +29,27 @@
29 29 #define TR_TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL)
30 30 #define TR_TREE_PARENT(node) (NULL!=(node)?(node)->parent:NULL)
31 31
  32 +/*
  33 + * Find data in a tree.
  34 + * Attention: This will change node, so normally you need to copy
  35 + * it before using this macro.
  36 + * Also be aware that found needs to be a valid lvalue and an integer.
  37 + */
  38 +#define TR_TREE_FIND(node, search, found, comp) \
  39 + (found) = -1; \
  40 + while((node) && ((node)->left || (node)->right)) { \
  41 + (found) = (comp)((node)->data, (search)); \
  42 + if (0 != (found)) { \
  43 + if (0 < (found)) { \
  44 + (node) = (node)->left; \
  45 + } else { \
  46 + (node) = (node)->right; \
  47 + } \
  48 + } else { \
  49 + break; \
  50 + } \
  51 + }
  52 +
32 53 #define TR_TREE_CHILD(node) \
33 54 (NULL==TR_TREE_RIGHT((node))?TR_TREE_LEFT((node)):TR_TREE_RIGHT((node)))
34 55
... ...
... ... @@ -28,35 +28,16 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
28 28 {
29 29 TR_Tree node = *this;
30 30 TR_Tree del_node;
  31 + int found;
31 32
32 33 void * data;
33 34
34   - /*
35   - * first search for it and if its found return the data
36   - * and we are done...
37   - */
38   - while (NULL != node) {
39   - int comparison = comp(node->data, search);
40   -
41   - if (0 < comparison) {
42   - node = TR_TREE_LEFT(node);
43   - continue;
44   - }
45   -
46   - if (0 > comparison) {
47   - node = TR_TREE_RIGHT(node);
48   - continue;
49   - }
50   -
51   - if (0 == comparison) {
52   - break;
53   - }
54   - }
  35 + TR_TREE_FIND(node, search, found, comp);
55 36
56 37 /*
57 38 * nothing was found...return NULL to indicate this.
58 39 */
59   - if (NULL == node) {
  40 + if (found != 0) {
60 41 return NULL;
61 42 }
62 43
... ...
... ... @@ -25,25 +25,12 @@
25 25 void *
26 26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
27 27 {
28   - while (NULL != this) {
29   - int comparison = comp(this->data, search);
  28 + TR_Tree node = this;
  29 + int found;
30 30
31   - if (0 < comparison) {
32   - this = TR_TREE_LEFT(this);
33   - continue;
34   - }
  31 + TR_TREE_FIND(node, search, found, comp);
35 32
36   - if (0 > comparison) {
37   - this = TR_TREE_RIGHT(this);
38   - continue;
39   - }
40   -
41   - if (0 == comparison) {
42   - break;
43   - }
44   - }
45   -
46   - return NULL != this ? this->data : NULL;
  33 + return found == 0 ? node->data : NULL;
47 34 }
48 35
49 36 // vim: set ts=4 sw=4:
... ...
... ... @@ -28,6 +28,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
28 28 {
29 29 TR_Tree node = *this;
30 30 TR_Tree new_node = NULL;
  31 + int found;
  32 +
  33 + TR_TREE_FIND(node, search, found, comp);
31 34
32 35 /*
33 36 * 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)
40 43 */
41 44 *this = node = new_node = TR_new(TR_Tree, search);
42 45 } else {
43   - /*
44   - * first search for it and if its found return the data
45   - * and we are done...
46   - */
47   - while (NULL != node) {
48   - int comparison = comp(node->data, search);
49   -
50   - if (0 < comparison) {
51   - if (NULL != TR_TREE_LEFT(node)) {
52   - node = TR_TREE_LEFT(node);
53   - continue;
54   - } else {
55   - node->left = TR_new(TR_Tree, search);
56   - node->left->parent = node;
57   - node = new_node = node->left;
58   - break;
59   - }
60   - }
61   -
62   - if (0 > comparison) {
63   - if (NULL != TR_TREE_RIGHT(node)) {
64   - node = TR_TREE_RIGHT(node);
65   - continue;
66   - } else {
67   - node->right = TR_new(TR_Tree, search);
68   - node->right->parent = node;
69   - node = new_node = node->right;
70   - break;
71   - }
72   - }
73   -
74   - if (0 == comparison) {
75   - // as this is insert and not find this will overwrite an existing value,
76   - // but return the previos one so that it can be freed if neccessary.
77   - void * data = node->data;
78   - node->data = (void *)search;
79   - return data;
  46 + if (found == 0) {
  47 + // we found an element
  48 + // as this is insert and not find this will overwrite an existing
  49 + // value, but return the previous one so that it can be freed if
  50 + // neccessary.
  51 + void * data = node->data;
  52 + node->data = (void *)search;
  53 + return data;
  54 + } else {
  55 + // not found
  56 + if (0 < found) {
  57 + node->left = TR_new(TR_Tree, search);
  58 + node->left->parent = node;
  59 + node = new_node = node->left;
  60 + } else {
  61 + node->right = TR_new(TR_Tree, search);
  62 + node->right->parent = node;
  63 + node = new_node = node->right;
80 64 }
81 65 }
82 66 }
... ... @@ -114,13 +98,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
114 98 && node->parent == node->parent->parent->left) {
115 99
116 100 TR_TREE_ROTATE(left, this, node->parent);
117   - node = TR_TREE_LEFT(node);
  101 + node = node->left;
118 102
119 103 } else if (node == node->parent->left
120 104 && node->parent == node->parent->parent->right) {
121 105
122 106 TR_TREE_ROTATE(right, this, node->parent);
123   - node = TR_TREE_RIGHT(node);
  107 + node = node->right;
124 108
125 109 }
126 110
... ...
... ... @@ -11,13 +11,13 @@
11 11 #define HAVE_MEMORY_H 1
12 12
13 13 /* Define to 1 if you have the `memset' function. */
14   -/* #undef HAVE_MEMSET */
  14 +#define HAVE_MEMSET 1
15 15
16 16 /* Define to 1 if you have the <stdarg.h> header file. */
17 17 #define HAVE_STDARG_H 1
18 18
19 19 /* Define to 1 if stdbool.h conforms to C99. */
20   -/* #undef HAVE_STDBOOL_H */
  20 +#define HAVE_STDBOOL_H 1
21 21
22 22 /* Define to 1 if you have the <stdint.h> header file. */
23 23 #define HAVE_STDINT_H 1
... ...
Please register or login to post a comment