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,6 +29,27 @@
29 #define TR_TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL) 29 #define TR_TREE_LEFT(node) (NULL!=(node)?(node)->left:NULL)
30 #define TR_TREE_PARENT(node) (NULL!=(node)?(node)->parent:NULL) 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 #define TR_TREE_CHILD(node) \ 53 #define TR_TREE_CHILD(node) \
33 (NULL==TR_TREE_RIGHT((node))?TR_TREE_LEFT((node)):TR_TREE_RIGHT((node))) 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,35 +28,16 @@ TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
28 { 28 {
29 TR_Tree node = *this; 29 TR_Tree node = *this;
30 TR_Tree del_node; 30 TR_Tree del_node;
  31 + int found;
31 32
32 void * data; 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 * nothing was found...return NULL to indicate this. 38 * nothing was found...return NULL to indicate this.
58 */ 39 */
59 - if (NULL == node) { 40 + if (found != 0) {
60 return NULL; 41 return NULL;
61 } 42 }
62 43
@@ -25,25 +25,12 @@ @@ -25,25 +25,12 @@
25 void * 25 void *
26 TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp) 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 // vim: set ts=4 sw=4: 36 // vim: set ts=4 sw=4:
@@ -28,6 +28,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp) @@ -28,6 +28,9 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
28 { 28 {
29 TR_Tree node = *this; 29 TR_Tree node = *this;
30 TR_Tree new_node = NULL; 30 TR_Tree new_node = NULL;
  31 + int found;
  32 +
  33 + TR_TREE_FIND(node, search, found, comp);
31 34
32 /* 35 /*
33 * insert the node or return the one in tree if comparison 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 +43,24 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
40 */ 43 */
41 *this = node = new_node = TR_new(TR_Tree, search); 44 *this = node = new_node = TR_new(TR_Tree, search);
42 } else { 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,13 +98,13 @@ TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
114 && node->parent == node->parent->parent->left) { 98 && node->parent == node->parent->parent->left) {
115 99
116 TR_TREE_ROTATE(left, this, node->parent); 100 TR_TREE_ROTATE(left, this, node->parent);
117 - node = TR_TREE_LEFT(node); 101 + node = node->left;
118 102
119 } else if (node == node->parent->left 103 } else if (node == node->parent->left
120 && node->parent == node->parent->parent->right) { 104 && node->parent == node->parent->parent->right) {
121 105
122 TR_TREE_ROTATE(right, this, node->parent); 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,13 +11,13 @@
11 #define HAVE_MEMORY_H 1 11 #define HAVE_MEMORY_H 1
12 12
13 /* Define to 1 if you have the `memset' function. */ 13 /* Define to 1 if you have the `memset' function. */
14 -/* #undef HAVE_MEMSET */ 14 +#define HAVE_MEMSET 1
15 15
16 /* Define to 1 if you have the <stdarg.h> header file. */ 16 /* Define to 1 if you have the <stdarg.h> header file. */
17 #define HAVE_STDARG_H 1 17 #define HAVE_STDARG_H 1
18 18
19 /* Define to 1 if stdbool.h conforms to C99. */ 19 /* Define to 1 if stdbool.h conforms to C99. */
20 -/* #undef HAVE_STDBOOL_H */ 20 +#define HAVE_STDBOOL_H 1
21 21
22 /* Define to 1 if you have the <stdint.h> header file. */ 22 /* Define to 1 if you have the <stdint.h> header file. */
23 #define HAVE_STDINT_H 1 23 #define HAVE_STDINT_H 1
Please register or login to post a comment