Mercurial > data_structures
changeset 7:b38243d51aea
A bit more on the bst
author | Eris Caffee <discordia@eldalin.com> |
---|---|
date | Wed, 26 Sep 2012 18:59:22 -0500 |
parents | 9f1e34c4a810 |
children | 6605a342e8f8 |
files | src/bst.c src/bst.h src/bst_test.c |
diffstat | 3 files changed, 236 insertions(+), 7 deletions(-) [+] |
line diff
1.1 --- a/src/bst.c Wed Sep 26 13:11:09 2012 -0500 1.2 +++ b/src/bst.c Wed Sep 26 18:59:22 2012 -0500 1.3 @@ -4,10 +4,16 @@ 1.4 #include "bst.h" 1.5 1.6 // Private functions. 1.7 -void bst_node_walk_inorder(struct bst_node * node, void (*op)(void * data)); 1.8 +void bst_data_walk_inorder(struct bst_node * node, void (*op)(void * data)); 1.9 +void bst_data_walk_preorder(struct bst_node * node, void (*op)(void * data)); 1.10 +void bst_data_walk_postorder(struct bst_node * node, void (*op)(void * data)); 1.11 + 1.12 +void bst_node_walk_postorder(struct bst_node * node, void (*op)(struct bst_node * n)); 1.13 + 1.14 void * bst_node_search(struct bst * bst, struct bst_node * node, void * data); 1.15 void * bst_node_minimum(struct bst_node * node); 1.16 void * bst_node_maximum(struct bst_node * node); 1.17 +void bst_node_free(struct bst_node * node); 1.18 1.19 //////////////////////////////////////////////////////////////////////////////// 1.20 struct bst * 1.21 @@ -37,13 +43,21 @@ 1.22 if (0 < bst->size) 1.23 { 1.24 // Walk the tree and delete the nodes. 1.25 - // This will cause memory leaks, so hopefully the user has already 1.26 + // This may cause memory leaks, so hopefully the user has already 1.27 // emptied the tree. 1.28 + bst_node_walk_postorder(bst->root, bst_node_free); 1.29 } 1.30 free(bst); 1.31 } 1.32 1.33 //////////////////////////////////////////////////////////////////////////////// 1.34 +void 1.35 +bst_node_free(struct bst_node * node) 1.36 + { 1.37 + free(node); 1.38 + } 1.39 + 1.40 +//////////////////////////////////////////////////////////////////////////////// 1.41 void * 1.42 bst_insert(struct bst * bst, void * data) 1.43 { 1.44 @@ -79,6 +93,7 @@ 1.45 else 1.46 p->right = new; 1.47 1.48 + bst->size++; 1.49 return new->data; 1.50 } 1.51 1.52 @@ -89,17 +104,68 @@ 1.53 if ( (NULL == bst) || (NULL == bst->root) || (NULL == op) ) 1.54 return; 1.55 1.56 - bst_node_walk_inorder(bst->root, op); 1.57 + bst_data_walk_inorder(bst->root, op); 1.58 } 1.59 1.60 //////////////////////////////////////////////////////////////////////////////// 1.61 -void bst_node_walk_inorder(struct bst_node * node, void (*op)(void * data)) 1.62 +void bst_walk_postorder(struct bst * bst, void (*op)(void * data)) 1.63 + { 1.64 + if ( (NULL == bst) || (NULL == bst->root) || (NULL == op) ) 1.65 + return; 1.66 + 1.67 + bst_data_walk_postorder(bst->root, op); 1.68 + } 1.69 + 1.70 +//////////////////////////////////////////////////////////////////////////////// 1.71 +void bst_walk_preorder(struct bst * bst, void (*op)(void * data)) 1.72 + { 1.73 + if ( (NULL == bst) || (NULL == bst->root) || (NULL == op) ) 1.74 + return; 1.75 + 1.76 + bst_data_walk_preorder(bst->root, op); 1.77 + } 1.78 + 1.79 +//////////////////////////////////////////////////////////////////////////////// 1.80 +void bst_data_walk_inorder(struct bst_node * node, void (*op)(void * data)) 1.81 { 1.82 if (NULL != node) 1.83 { 1.84 - bst_node_walk_inorder(node->left, op); 1.85 + bst_data_walk_inorder(node->left, op); 1.86 op(node->data); 1.87 - bst_node_walk_inorder(node->right, op); 1.88 + bst_data_walk_inorder(node->right, op); 1.89 + } 1.90 + } 1.91 + 1.92 +//////////////////////////////////////////////////////////////////////////////// 1.93 +void bst_data_walk_postorder(struct bst_node * node, void (*op)(void * data)) 1.94 + { 1.95 + if (NULL != node) 1.96 + { 1.97 + bst_data_walk_postorder(node->left, op); 1.98 + bst_data_walk_postorder(node->right, op); 1.99 + op(node->data); 1.100 + } 1.101 + } 1.102 + 1.103 +//////////////////////////////////////////////////////////////////////////////// 1.104 +void bst_data_walk_preorder(struct bst_node * node, void (*op)(void * data)) 1.105 + { 1.106 + if (NULL != node) 1.107 + { 1.108 + op(node->data); 1.109 + bst_data_walk_preorder(node->left, op); 1.110 + bst_data_walk_preorder(node->right, op); 1.111 + } 1.112 + } 1.113 + 1.114 +//////////////////////////////////////////////////////////////////////////////// 1.115 +void bst_node_walk_postorder(struct bst_node * node, void (*op)(struct bst_node * n)) 1.116 + { 1.117 + if (NULL != node) 1.118 + { 1.119 + bst_node_walk_postorder(node->left, op); 1.120 + bst_node_walk_postorder(node->right, op); 1.121 + op(node); 1.122 } 1.123 } 1.124 1.125 @@ -188,3 +254,109 @@ 1.126 return NULL; 1.127 return node->data; 1.128 } 1.129 + 1.130 +//////////////////////////////////////////////////////////////////////////////// 1.131 +struct bst_iterator * bst_begin(struct bst * bst) 1.132 + { 1.133 + if ( (NULL == bst) || (NULL == bst->root) ) 1.134 + return NULL; 1.135 + 1.136 + struct bst_node * min = bst->root; 1.137 + while (min->left) 1.138 + min = min->left; 1.139 + 1.140 + struct bst_iterator * it = malloc(sizeof(struct bst_iterator)); 1.141 + if (NULL == it) 1.142 + return NULL; 1.143 + 1.144 + it->bst = bst; 1.145 + it->curr = min; 1.146 + return it; 1.147 + } 1.148 + 1.149 +//////////////////////////////////////////////////////////////////////////////// 1.150 +struct bst_iterator * bst_end(struct bst * bst) 1.151 + { 1.152 + if ( (NULL == bst) || (NULL == bst->root) ) 1.153 + return NULL; 1.154 + 1.155 + struct bst_node * max = bst->root; 1.156 + while (max->right) 1.157 + max = max->right; 1.158 + 1.159 + struct bst_iterator * it = malloc(sizeof(struct bst_iterator)); 1.160 + if (NULL == it) 1.161 + return NULL; 1.162 + 1.163 + it->bst = bst; 1.164 + it->curr = max; 1.165 + return it; 1.166 + } 1.167 + 1.168 +//////////////////////////////////////////////////////////////////////////////// 1.169 +struct bst_iterator * bst_next(struct bst_iterator * it) 1.170 + { 1.171 + if ( (NULL == it) || (NULL == it->bst) || (NULL == it->curr) ) 1.172 + return NULL; 1.173 + 1.174 + if (NULL == it->curr->right) 1.175 + { 1.176 + struct bst_node * p = it->curr; 1.177 + it->curr = it->curr->parent; 1.178 + while ( (NULL != it->curr) && (p == it->curr->right) ) 1.179 + { 1.180 + p = it->curr; 1.181 + it->curr = it->curr->parent; 1.182 + } 1.183 + 1.184 + if (it->curr == NULL) 1.185 + return NULL; 1.186 + } 1.187 + else 1.188 + { 1.189 + struct bst_node * min = it->curr->right; 1.190 + while (min->left) 1.191 + min = min->left; 1.192 + it->curr = min; 1.193 + } 1.194 + return it; 1.195 + } 1.196 + 1.197 +//////////////////////////////////////////////////////////////////////////////// 1.198 +struct bst_iterator * bst_prev(struct bst_iterator * it) 1.199 + { 1.200 + if ( (NULL == it) || (NULL == it->bst) || (NULL == it->curr) ) 1.201 + return NULL; 1.202 + 1.203 + if (NULL == it->curr->left) 1.204 + { 1.205 + struct bst_node * p = it->curr; 1.206 + it->curr = it->curr->parent; 1.207 + while ( (NULL != it->curr) && (p == it->curr->left) ) 1.208 + { 1.209 + p = it->curr; 1.210 + it->curr = it->curr->parent; 1.211 + } 1.212 + 1.213 + if (it->curr == NULL) 1.214 + return NULL; 1.215 + } 1.216 + else 1.217 + { 1.218 + struct bst_node * max = it->curr->left; 1.219 + while (max->right) 1.220 + max = max->right; 1.221 + it->curr = max; 1.222 + } 1.223 + return it; 1.224 + } 1.225 + 1.226 +//////////////////////////////////////////////////////////////////////////////// 1.227 +void * bst_value(struct bst_iterator * it) 1.228 + { 1.229 + if ( (NULL == it) || (NULL == it->bst) || (NULL == it->curr) ) 1.230 + return NULL; 1.231 + 1.232 + return it->curr->data; 1.233 + } 1.234 +
2.1 --- a/src/bst.h Wed Sep 26 13:11:09 2012 -0500 2.2 +++ b/src/bst.h Wed Sep 26 18:59:22 2012 -0500 2.3 @@ -20,6 +20,12 @@ 2.4 bool (*eq)(void * a, void * b); 2.5 }; 2.6 2.7 +struct bst_iterator 2.8 + { 2.9 + struct bst * bst; 2.10 + struct bst_node * curr; 2.11 + }; 2.12 + 2.13 struct bst * bst_new(bool (*le)(void * a, void * b), bool (*eq)(void * a, void * b)); 2.14 void bst_delete(struct bst * bst); 2.15 2.16 @@ -32,5 +38,14 @@ 2.17 void * bst_maximum(struct bst * bst); 2.18 2.19 void bst_walk_inorder(struct bst * bst, void (*op)(void * data)); 2.20 +void bst_walk_preorder(struct bst * bst, void (*op)(void * data)); 2.21 +void bst_walk_postorder(struct bst * bst, void (*op)(void * data)); 2.22 + 2.23 + 2.24 +struct bst_iterator * bst_begin(struct bst * bst); 2.25 +struct bst_iterator * bst_end(struct bst * bst); 2.26 +struct bst_iterator * bst_next(struct bst_iterator * it); 2.27 +struct bst_iterator * bst_prev(struct bst_iterator * it); 2.28 +void * bst_value(struct bst_iterator * it); 2.29 2.30 #endif
3.1 --- a/src/bst_test.c Wed Sep 26 13:11:09 2012 -0500 3.2 +++ b/src/bst_test.c Wed Sep 26 18:59:22 2012 -0500 3.3 @@ -22,6 +22,11 @@ 3.4 printf("%d\n", *((int *) d) ); 3.5 } 3.6 3.7 +void free_data(void * d) 3.8 + { 3.9 + free(d); 3.10 + } 3.11 + 3.12 int main(int argc, char ** argv) 3.13 { 3.14 struct bst * bst = bst_new(le, eq); 3.15 @@ -31,6 +36,8 @@ 3.16 exit(EXIT_FAILURE); 3.17 } 3.18 3.19 + //////////////////////////////////////// 3.20 + printf ("======================\nGenerating\n"); 3.21 //srand(time()); 3.22 int * ip; 3.23 for (int i = 0 ; i < MAX_NUMS ; ++i) 3.24 @@ -43,16 +50,20 @@ 3.25 } 3.26 3.27 *ip = rand(); 3.28 - 3.29 + printf("%d\n", *ip); 3.30 if (NULL == bst_insert(bst, ip)) 3.31 { 3.32 perror("bst_insert"); 3.33 exit(EXIT_FAILURE); 3.34 } 3.35 } 3.36 + printf ("======================\n"); 3.37 3.38 + 3.39 + //////////////////////////////////////// 3.40 bst_walk_inorder(bst, print); 3.41 3.42 + //////////////////////////////////////// 3.43 int i = 1; 3.44 int * p = (int *) bst_search(bst, &i); 3.45 if (NULL == p) 3.46 @@ -87,5 +98,36 @@ 3.47 else 3.48 printf("%d MAXIMUM\n", *max); 3.49 3.50 + //////////////////////////////////////// 3.51 + printf("\n\nWalking inorder with iterators\n"); 3.52 + struct bst_iterator * it = bst_begin(bst); 3.53 + if (NULL == it) 3.54 + { 3.55 + perror("bst_begin"); 3.56 + exit(EXIT_FAILURE); 3.57 + } 3.58 + do 3.59 + printf("%d\n", *((int *) bst_value(it))); 3.60 + while (bst_next(it)); 3.61 + free(it); 3.62 + 3.63 + 3.64 + //////////////////////////////////////// 3.65 + printf("\n\nWalking reverse inorder with iterators\n"); 3.66 + it = bst_end(bst); 3.67 + if (NULL == it) 3.68 + { 3.69 + perror("bst_end"); 3.70 + exit(EXIT_FAILURE); 3.71 + } 3.72 + do 3.73 + printf("%d\n", *((int *) bst_value(it))); 3.74 + while (bst_prev(it)); 3.75 + free(it); 3.76 + 3.77 + 3.78 + bst_walk_inorder(bst, free_data); 3.79 + bst_delete(bst); 3.80 + 3.81 exit(EXIT_SUCCESS); 3.82 }