00001 #include "../stdafx.h"
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <assert.h>
00006 #include "ptree.h"
00007
00008
00009
00010 struct ptree_node {
00011 void *pn_value;
00012 struct ptree_node *pn_parent;
00013 struct ptree_node *pn_left;
00014 struct ptree_node *pn_right;
00015 };
00016
00017 static int
00018 _walk_to(void *v,
00019 struct ptree_node **startp,
00020 struct ptree_node ***pp,
00021 int (*cmp)(const void *v1, const void *v2))
00022 {
00023 struct ptree_node **nextp;
00024 int c = -1;
00025
00026 nextp = startp;
00027 while (*nextp)
00028 {
00029 c = cmp(v, (*nextp)->pn_value);
00030 *startp = *nextp;
00031 if (c == 0)
00032 break;
00033 if (c < 0)
00034 nextp = &(*nextp)->pn_left;
00035 else
00036 nextp = &(*nextp)->pn_right;
00037 if (pp)
00038 *pp = nextp;
00039 }
00040
00041 return c;
00042 }
00043
00044
00045 static ptree_walk_res_t
00046 _visit(struct ptree_node *pn,
00047 int level,
00048 void *arg1,
00049 void *arg2)
00050 {
00051 ptree_walk_res_t (*func)(const void *, int, void *, void *) = arg1;
00052
00053 return func(pn->pn_value, level, arg2, pn);
00054 }
00055
00056 static ptree_node_t *
00057 _find_min(ptree_node_t *pn,
00058 int *levelp)
00059 {
00060 while (pn->pn_left)
00061 {
00062 pn = pn->pn_left;
00063 if (levelp)
00064 (*levelp)++;
00065 }
00066 return pn;
00067 }
00068
00069 static ptree_node_t *
00070 _find_succ(ptree_node_t *pn,
00071 int *levelp)
00072 {
00073 if (pn->pn_right)
00074 {
00075 pn = pn->pn_right;
00076 if (levelp)
00077 (*levelp)++;
00078 while (pn->pn_left)
00079 {
00080 pn = pn->pn_left;
00081 if (levelp)
00082 (*levelp)++;
00083 }
00084 }
00085 else
00086 {
00087 while (pn->pn_parent && pn->pn_parent->pn_right == pn)
00088 {
00089 pn = pn->pn_parent;
00090 if (levelp)
00091 (*levelp)--;
00092 }
00093 pn = pn->pn_parent;
00094 if (levelp)
00095 (*levelp)--;
00096 }
00097
00098 return pn;
00099 }
00100
00101 static int
00102 _walk_int(struct ptree_node *pn,
00103 ptree_order_t order,
00104 int level,
00105 ptree_walk_res_t (*func)(struct ptree_node *, int level, void *, void *),
00106 void *arg1,
00107 void *arg2)
00108 {
00109 ptree_walk_res_t res;
00110 ptree_node_t *next;
00111
00112 if (!pn)
00113 return PTREE_WALK_CONTINUE;
00114
00115 if (order == PTREE_INORDER)
00116 {
00117 int nlevel;
00118
00119 pn = _find_min(pn, &level);
00120 while (pn)
00121 {
00122 nlevel = level;
00123 next = _find_succ(pn, &nlevel);
00124 if ((res = func(pn, level, arg1, arg2)) != PTREE_WALK_CONTINUE)
00125 return res;
00126 level = nlevel;
00127 if (level < 0)
00128 level = 0;
00129 pn = next;
00130 }
00131 return PTREE_WALK_CONTINUE;
00132 }
00133 if (order == PTREE_PREORDER && (res = func(pn, level, arg1, arg2)) != PTREE_WALK_CONTINUE)
00134 return res;
00135 if ((res = _walk_int(pn->pn_left, order, level + 1, func, arg1, arg2)) != PTREE_WALK_CONTINUE)
00136 return res;
00137 if ((res = _walk_int(pn->pn_right, order, level + 1, func, arg1, arg2)) != PTREE_WALK_CONTINUE)
00138 return res;
00139 if (order == PTREE_POSTORDER && (res = func(pn, level, arg1, arg2)) != PTREE_WALK_CONTINUE)
00140 return res;
00141 return PTREE_WALK_CONTINUE;
00142 }
00143
00144 #ifdef VERIFY_TREE
00145 static ptree_walk_res_t
00146 _count(struct ptree_node *pn,
00147 int level,
00148 void *arg1,
00149 void *arg2)
00150 {
00151 int *counter = arg1;
00152 (*counter)++;
00153 return PTREE_WALK_CONTINUE;
00154 }
00155
00156
00157 static int
00158 _count_nodes(ptree_node_t **rootp)
00159 {
00160 int counter = 0;
00161 _walk_int(*rootp, PTREE_INORDER, 0, _count, &counter, 0);
00162 return counter;
00163 }
00164
00165 static ptree_walk_res_t
00166 _verify_node(struct ptree_node *pn,
00167 int level,
00168 void *arg1,
00169 void *arg2)
00170 {
00171 int (*cmp)(const void *v1, const void *v2) = arg1;
00172 struct ptree_node **prev_pn_p = (struct ptree_node **)arg2;
00173 struct ptree_node *prev_pn = *prev_pn_p;
00174
00175 if(pn->pn_left != NULL && pn->pn_left->pn_parent != pn)
00176 return PTREE_WALK_STOP;
00177 if(pn->pn_right != NULL && pn->pn_right->pn_parent != pn)
00178 return PTREE_WALK_STOP;
00179
00180 if(prev_pn != NULL)
00181 {
00182
00183 if(cmp(pn->pn_value, prev_pn->pn_value) <= 0)
00184 return PTREE_WALK_STOP;
00185 }
00186 *prev_pn_p = pn;
00187
00188 return PTREE_WALK_CONTINUE;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 static int
00209 _verify_tree(ptree_node_t **rootp, int (*cmp)(const void *v1, const void *v2))
00210 {
00211 struct ptree_node *prev_pn = NULL;
00212 if(_walk_int(*rootp, PTREE_INORDER, 0, _verify_node, cmp, &prev_pn) == PTREE_WALK_STOP)
00213 return 0;
00214 return 1;
00215 }
00216 #endif
00217
00218 static void
00219 _remove_node(ptree_node_t **rootp,
00220 ptree_node_t *pn,
00221 void **oldval)
00222 {
00223 ptree_node_t **pp;
00224 ptree_node_t **predp;
00225 ptree_node_t *pred;
00226
00227 #ifdef VERIFY_TREE
00228 int countStart = _count_nodes(rootp), countEnd=0;
00229 #endif
00230
00231
00232 if (!pn->pn_parent)
00233 {
00234 assert(rootp && pn == *rootp);
00235 pp = rootp;
00236 }
00237 else
00238 {
00239 if (pn->pn_parent->pn_left == pn)
00240 pp = &pn->pn_parent->pn_left;
00241 else
00242 pp = &pn->pn_parent->pn_right;
00243 }
00244
00245
00246 assert(pp);
00247
00248
00249 if (!pn->pn_left)
00250 {
00251 *pp = pn->pn_right;
00252 if (pn->pn_right)
00253 pn->pn_right->pn_parent = pn->pn_parent;
00254 }
00255 else if (!pn->pn_right)
00256 {
00257 *pp = pn->pn_left;
00258 if (pn->pn_left)
00259 pn->pn_left->pn_parent = pn->pn_parent;
00260 }
00261
00262
00263 else
00264 {
00265 for (predp = &pn->pn_left; (*predp)->pn_right; )
00266 predp = &(*predp)->pn_right;
00267 pred = *predp;
00268
00269
00270 if (pred->pn_parent->pn_left == pred)
00271 pred->pn_parent->pn_left = pred->pn_left;
00272 else
00273 pred->pn_parent->pn_right = pred->pn_left;
00274 if(pred->pn_left)
00275 pred->pn_left->pn_parent = pred->pn_parent;
00276
00277 *pp = pred;
00278
00279 pred->pn_parent = pn->pn_parent;
00280 pred->pn_left = pn->pn_left;
00281 pred->pn_right = pn->pn_right;
00282
00283 if (pn->pn_left)
00284 pn->pn_left->pn_parent = pred;
00285 pn->pn_right->pn_parent = pred;
00286 }
00287
00288
00289 if (oldval)
00290 *oldval = pn->pn_value;
00291
00292 free(pn);
00293
00294 #ifdef VERIFY_TREE
00295 countEnd = _count_nodes(rootp);
00296 countStart--;
00297 assert(countEnd == countStart);
00298 #endif
00299 }
00300
00301 int
00302 ptree_inorder_walk_remove(ptree_node_t **rootp,
00303 void **oldval,
00304 void *pn,
00305 int (*cmp)(const void *v1, const void *v2))
00306 {
00307 assert(pn);
00308 if (!pn)
00309 return 0;
00310 #ifdef VERIFY_TREE
00311 assert(_verify_tree(rootp, cmp));
00312 #endif
00313 _remove_node(rootp, pn, oldval);
00314 #ifdef VERIFY_TREE
00315 assert(_verify_tree(rootp, cmp));
00316 #endif
00317 return 1;
00318 }
00319
00320 ptree_walk_res_t
00321 ptree_walk(ptree_node_t *start,
00322 ptree_order_t order,
00323 ptree_walk_res_t (*func)(const void *v1, int level, void *arg, void *ptree_inorder_walking_remove_arg),
00324 int (*cmp)(const void *v1, const void *v2),
00325 void *arg)
00326 {
00327 #ifdef VERIFY_TREE
00328 ptree_node_t *start_p = start;
00329 if(cmp != NULL)
00330 assert(_verify_tree(&start_p, cmp));
00331 #endif
00332
00333 return _walk_int((struct ptree_node *)start, order, 0, _visit, (void *)func, arg);
00334 }
00335
00336 ptree_walk_res_t
00337 ptree_clear_func(struct ptree_node *pn,
00338 int level,
00339 void *arg1,
00340 void *arg2)
00341 {
00342 free(pn); pn = NULL;
00343
00344 return PTREE_WALK_CONTINUE;
00345 }
00346
00347 void
00348 ptree_clear(ptree_node_t **rootp)
00349 {
00350 _walk_int(*rootp, PTREE_POSTORDER, 0, ptree_clear_func, 0, 0);
00351 *rootp = 0;
00352 }
00353
00354 int
00355 ptree_remove(void *v,
00356 ptree_node_t **rootp,
00357 int (*cmp)(const void *v1, const void *v2),
00358 void **oldval)
00359 {
00360 struct ptree_node *cur;
00361
00362 #ifdef VERIFY_TREE
00363 assert(_verify_tree(rootp, cmp));
00364 #endif
00365
00366 cur = *rootp;
00367 if (_walk_to(v, &cur, NULL, cmp) != 0)
00368 return 0;
00369 _remove_node(rootp, cur, oldval);
00370
00371 #ifdef VERIFY_TREE
00372 assert(_verify_tree(rootp, cmp));
00373 #endif
00374
00375 return 1;
00376 }
00377
00378 int
00379 ptree_replace(void *v,
00380 ptree_node_t **rootp,
00381 int (*cmp)(const void *v1, const void *v2),
00382 void **oldval)
00383 {
00384 struct ptree_node **parentpp;
00385 struct ptree_node *parentp;
00386 struct ptree_node *pn;
00387 int c;
00388
00389 #ifdef VERIFY_TREE
00390 int countStart = _count_nodes(rootp), countEnd=0;
00391 #endif
00392
00393 parentp = *rootp;
00394 parentpp = rootp;
00395
00396 #ifdef VERIFY_TREE
00397 assert(_verify_tree(rootp, cmp));
00398 #endif
00399
00400
00401 if ((c = _walk_to(v, &parentp, &parentpp, cmp)) == 0)
00402 {
00403 if (oldval)
00404 *oldval = parentp->pn_value;
00405 parentp->pn_value = v;
00406
00407 #ifdef VERIFY_TREE
00408 assert(_verify_tree(rootp, cmp));
00409 #endif
00410
00411 #ifdef VERIFY_TREE
00412 countEnd = _count_nodes(rootp);
00413 assert(countEnd == countStart);
00414 #endif
00415
00416 return 1;
00417 }
00418
00419
00420 if (!(pn = malloc(sizeof (*pn))))
00421 return 0;
00422
00423 memset(pn, 0, sizeof (*pn));
00424 pn->pn_value = v;
00425 pn->pn_parent = parentp;
00426 *parentpp = pn;
00427 if (oldval)
00428 *oldval = 0;
00429
00430 #ifdef VERIFY_TREE
00431 assert(_verify_tree(rootp, cmp));
00432 #endif
00433
00434 #ifdef VERIFY_TREE
00435 countEnd = _count_nodes(rootp);
00436 countStart++;
00437 assert(countEnd == countStart);
00438 #endif
00439
00440 return 1;
00441 }
00442
00443 int
00444 ptree_contains(void *v,
00445 ptree_node_t *parentp,
00446 int (*cmp)(const void *v1, const void *v2),
00447 void **nodeval)
00448 {
00449 int c;
00450
00451 if ((c = _walk_to(v, &parentp, NULL, cmp)) == 0)
00452 {
00453 if (nodeval)
00454 *nodeval = parentp->pn_value;
00455 return 1;
00456 }
00457 if (nodeval)
00458 *nodeval = 0;
00459 return 0;
00460 }