#include <stdio.h>
#include <stdlib.h>
#include "vixie.h"
#include "tree.h"
#include "debug.h"
Include dependency graph for tree.c:
Go to the source code of this file.
Defines | |
#define | __P(x) () |
Functions | |
static void sprout | __P ((tree **, tree_t, int *, int(*)(), void(*)())) |
static int delete | __P ((tree **, int(*)(), tree_t, void(*)(), int *, int *)) |
static void del | __P ((tree **, int *, tree **, void(*)(), int *)) |
static void bal_L | __P ((tree **, int *)) |
void | tree_init (tree **ppr_tree) |
tree_t | tree_srch (tree **ppr_tree, int(*pfi_compare)(), tree_t p_user) |
void | tree_add (tree **ppr_tree, int(*pfi_compare)(), tree_t p_user, void(*pfv_uar)()) |
int | tree_delete (tree **ppr_p, int(*pfi_compare)(), tree_t p_user, void(*pfv_uar)()) |
int | tree_trav (tree **ppr_tree, int(*pfi_uar)()) |
void | tree_mung (tree **ppr_tree, void(*pfv_uar)()) |
static void | sprout (tree **ppr, tree_t p_data, int *pi_balance, int(*pfi_compare)(), void(*pfv_delete)()) |
static int | delete (tree **ppr_p, int(*pfi_compare)(), tree_t p_user, void(*pfv_uar)(), int *pi_balance, int *pi_uar_called) |
static void | del (tree **ppr_r, int *pi_balance, tree **ppr_q, void(*pfv_uar)(), int *pi_uar_called) |
static void | bal_L (tree **ppr_p, int *pi_balance) |
static void | bal_R (tree **ppr_p, int *pi_balance) |
static void bal_R __P | ( | (tree **, int *) | ) | [static] |
static void bal_L | ( | tree ** | ppr_p, | |
int * | pi_balance | |||
) | [static] |
Definition at line 360 of file tree.c.
References dprintk, ENTER, EXITV, FALSE, tree_s::tree_b, tree_s::tree_l, and tree_s::tree_r.
Referenced by delete().
00361 { 00362 tree *p1, *p2; 00363 int b1, b2; 00364 00365 ENTER("bal_L"); 00366 dprintk("left branch has shrunk"); 00367 00368 switch ((*ppr_p)->tree_b) { 00369 case -1: 00370 dprintk("was imbalanced, fixed implicitly"); 00371 (*ppr_p)->tree_b = 0; 00372 break; 00373 case 0: 00374 dprintk("was okay, is now one off"); 00375 (*ppr_p)->tree_b = 1; 00376 *pi_balance = FALSE; 00377 break; 00378 case 1: 00379 dprintk("was already off, this is too much"); 00380 p1 = (*ppr_p)->tree_r; 00381 b1 = p1->tree_b; 00382 if (b1 >= 0) { 00383 dprintk("single RR"); 00384 (*ppr_p)->tree_r = p1->tree_l; 00385 p1->tree_l = *ppr_p; 00386 if (b1 == 0) { 00387 dprintk("b1 == 0"); 00388 (*ppr_p)->tree_b = 1; 00389 p1->tree_b = -1; 00390 *pi_balance = FALSE; 00391 } else { 00392 dprintk("b1 != 0"); 00393 (*ppr_p)->tree_b = 0; 00394 p1->tree_b = 0; 00395 } 00396 *ppr_p = p1; 00397 } else { 00398 dprintk("double RL"); 00399 p2 = p1->tree_l; 00400 b2 = p2->tree_b; 00401 p1->tree_l = p2->tree_r; 00402 p2->tree_r = p1; 00403 (*ppr_p)->tree_r = p2->tree_l; 00404 p2->tree_l = *ppr_p; 00405 if (b2 == 1) 00406 (*ppr_p)->tree_b = -1; 00407 else 00408 (*ppr_p)->tree_b = 0; 00409 if (b2 == -1) 00410 p1->tree_b = 1; 00411 else 00412 p1->tree_b = 0; 00413 *ppr_p = p2; 00414 p2->tree_b = 0; 00415 } 00416 } 00417 EXITV; 00418 }
static void bal_R | ( | tree ** | ppr_p, | |
int * | pi_balance | |||
) | [static] |
Definition at line 421 of file tree.c.
References dprintk, ENTER, EXITV, FALSE, tree_s::tree_b, tree_s::tree_l, and tree_s::tree_r.
Referenced by del(), and delete().
00422 { 00423 tree *p1, *p2; 00424 int b1, b2; 00425 00426 ENTER("bal_R"); 00427 dprintk("right branch has shrunk"); 00428 switch ((*ppr_p)->tree_b) { 00429 case 1: 00430 dprintk("was imbalanced, fixed implicitly"); 00431 (*ppr_p)->tree_b = 0; 00432 break; 00433 case 0: 00434 dprintk("was okay, is now one off"); 00435 (*ppr_p)->tree_b = -1; 00436 *pi_balance = FALSE; 00437 break; 00438 case -1: 00439 dprintk("was already off, this is too much"); 00440 p1 = (*ppr_p)->tree_l; 00441 b1 = p1->tree_b; 00442 if (b1 <= 0) { 00443 dprintk("single LL"); 00444 (*ppr_p)->tree_l = p1->tree_r; 00445 p1->tree_r = *ppr_p; 00446 if (b1 == 0) { 00447 dprintk("b1 == 0"); 00448 (*ppr_p)->tree_b = -1; 00449 p1->tree_b = 1; 00450 *pi_balance = FALSE; 00451 } else { 00452 dprintk("b1 != 0"); 00453 (*ppr_p)->tree_b = 0; 00454 p1->tree_b = 0; 00455 } 00456 *ppr_p = p1; 00457 } else { 00458 dprintk("double LR"); 00459 p2 = p1->tree_r; 00460 b2 = p2->tree_b; 00461 p1->tree_r = p2->tree_l; 00462 p2->tree_l = p1; 00463 (*ppr_p)->tree_l = p2->tree_r; 00464 p2->tree_r = *ppr_p; 00465 if (b2 == -1) 00466 (*ppr_p)->tree_b = 1; 00467 else 00468 (*ppr_p)->tree_b = 0; 00469 if (b2 == 1) 00470 p1->tree_b = -1; 00471 else 00472 p1->tree_b = 0; 00473 *ppr_p = p2; 00474 p2->tree_b = 0; 00475 } 00476 } 00477 EXITV; 00478 }
static void del | ( | tree ** | ppr_r, | |
int * | pi_balance, | |||
tree ** | ppr_q, | |||
void(*)() | pfv_uar, | |||
int * | pi_uar_called | |||
) | [static] |
Definition at line 337 of file tree.c.
References bal_R(), ENTER, EXITV, tree_s::tree_l, and TRUE.
Referenced by delete().
00339 { 00340 ENTER("del"); 00341 00342 if ((*ppr_r)->tree_r != NULL) { 00343 del(&(*ppr_r)->tree_r, pi_balance, ppr_q, pfv_uar, pi_uar_called); 00344 if (*pi_balance) 00345 bal_R(ppr_r, pi_balance); 00346 } else { 00347 if (pfv_uar) 00348 (*pfv_uar) ((*ppr_q)->tree_p); 00349 *pi_uar_called = TRUE; 00350 (*ppr_q)->tree_p = (*ppr_r)->tree_p; 00351 *ppr_q = *ppr_r; 00352 *ppr_r = (*ppr_r)->tree_l; 00353 *pi_balance = TRUE; 00354 } 00355 00356 EXITV; 00357 }
static int delete | ( | tree ** | ppr_p, | |
int(*)() | pfi_compare, | |||
tree_t | p_user, | |||
void(*)() | pfv_uar, | |||
int * | pi_balance, | |||
int * | pi_uar_called | |||
) | [static] |
Definition at line 281 of file tree.c.
References bal_L(), bal_R(), del(), dprintk, ENTER, EXIT, FALSE, i_comp(), tree_s::tree_l, tree_s::tree_p, tree_s::tree_r, and TRUE.
00284 { 00285 tree *pr_q; 00286 int i_comp, i_ret; 00287 00288 ENTER("delete"); 00289 00290 if (*ppr_p == NULL) { 00291 dprintk("key not in tree"); 00292 EXIT(FALSE); 00293 } 00294 00295 i_comp = (*pfi_compare) ((*ppr_p)->tree_p, p_user); 00296 00297 if (i_comp > 0) { 00298 dprintk("too high - scan left"); 00299 i_ret = 00300 delete(&(*ppr_p)->tree_l, pfi_compare, p_user, pfv_uar, 00301 pi_balance, pi_uar_called); 00302 if (*pi_balance) 00303 bal_L(ppr_p, pi_balance); 00304 } else if (i_comp < 0) { 00305 dprintk("too low - scan right"); 00306 i_ret = 00307 delete(&(*ppr_p)->tree_r, pfi_compare, p_user, pfv_uar, 00308 pi_balance, pi_uar_called); 00309 if (*pi_balance) 00310 bal_R(ppr_p, pi_balance); 00311 } else { 00312 dprintk("equal"); 00313 pr_q = *ppr_p; 00314 if (pr_q->tree_r == NULL) { 00315 dprintk("right subtree null"); 00316 *ppr_p = pr_q->tree_l; 00317 *pi_balance = TRUE; 00318 } else if (pr_q->tree_l == NULL) { 00319 dprintk("right subtree non-null, left subtree null"); 00320 *ppr_p = pr_q->tree_r; 00321 *pi_balance = TRUE; 00322 } else { 00323 dprintk("neither subtree null"); 00324 del(&pr_q->tree_l, pi_balance, &pr_q, pfv_uar, pi_uar_called); 00325 if (*pi_balance) 00326 bal_L(ppr_p, pi_balance); 00327 } 00328 if (!*pi_uar_called && *pfv_uar) 00329 (*pfv_uar) (pr_q->tree_p); 00330 free(pr_q); /* thanks to wuth@castrov.cuc.ab.ca */ 00331 i_ret = TRUE; 00332 } 00333 EXIT(i_ret); 00334 }
static void sprout | ( | tree ** | ppr, | |
tree_t | p_data, | |||
int * | pi_balance, | |||
int(*)() | pfi_compare, | |||
void(*)() | pfv_delete | |||
) | [static] |
Definition at line 129 of file tree.c.
References dprintk, ENTER, EXITV, FALSE, tree_s::tree_b, tree_s::tree_l, tree_s::tree_r, and TRUE.
Referenced by tree_add().
00132 { 00133 tree *p1, *p2; 00134 int cmp; 00135 00136 ENTER("sprout"); 00137 00138 /* are we grounded? if so, add the node "here" and set the rebalance 00139 * flag, then exit. 00140 */ if (!*ppr) { 00141 dprintk("grounded. adding new node, setting h=true"); 00142 *ppr = (tree *) malloc(sizeof(tree)); 00143 (*ppr)->tree_l = NULL; 00144 (*ppr)->tree_r = NULL; 00145 (*ppr)->tree_b = 0; 00146 (*ppr)->tree_p = p_data; 00147 *pi_balance = TRUE; 00148 EXITV; 00149 } 00150 00151 /* compare the data using routine passed by caller. 00152 */ 00153 cmp = (*pfi_compare) (p_data, (*ppr)->tree_p); 00154 00155 /* if LESS, prepare to move to the left. 00156 */ 00157 if (cmp < 0) { 00158 dprintk("LESS. sprouting left."); 00159 sprout(&(*ppr)->tree_l, p_data, pi_balance, pfi_compare, 00160 pfv_delete); 00161 if (*pi_balance) { /* left branch has grown longer */ 00162 dprintk("LESS: left branch has grown"); 00163 switch ((*ppr)->tree_b) { 00164 case 1: /* right branch WAS longer; balance is ok now */ 00165 dprintk("LESS: case 1.. balnce restored implicitly"); 00166 (*ppr)->tree_b = 0; 00167 *pi_balance = FALSE; 00168 break; 00169 case 0: /* balance WAS okay; now left branch longer */ 00170 dprintk("LESS: case 0.. balnce bad but still ok"); 00171 (*ppr)->tree_b = -1; 00172 break; 00173 case -1: 00174 /* left branch was already too long. rebalnce */ 00175 dprintk("LESS: case -1: rebalancing"); 00176 p1 = (*ppr)->tree_l; 00177 if (p1->tree_b == -1) { /* LL */ 00178 dprintk("LESS: single LL"); 00179 (*ppr)->tree_l = p1->tree_r; 00180 p1->tree_r = *ppr; 00181 (*ppr)->tree_b = 0; 00182 *ppr = p1; 00183 } else { /* double LR */ 00184 dprintk("LESS: double LR"); 00185 00186 p2 = p1->tree_r; 00187 p1->tree_r = p2->tree_l; 00188 p2->tree_l = p1; 00189 00190 (*ppr)->tree_l = p2->tree_r; 00191 p2->tree_r = *ppr; 00192 00193 if (p2->tree_b == -1) 00194 (*ppr)->tree_b = 1; 00195 else 00196 (*ppr)->tree_b = 0; 00197 00198 if (p2->tree_b == 1) 00199 p1->tree_b = -1; 00200 else 00201 p1->tree_b = 0; 00202 *ppr = p2; 00203 } /*else */ 00204 (*ppr)->tree_b = 0; 00205 *pi_balance = FALSE; 00206 } /*switch */ 00207 } /*if */ 00208 EXITV; 00209 } 00210 00211 /*if */ 00212 /* if MORE, prepare to move to the right. 00213 */ 00214 if (cmp > 0) { 00215 dprintk("MORE: sprouting to the right"); 00216 sprout(&(*ppr)->tree_r, p_data, pi_balance, pfi_compare, 00217 pfv_delete); 00218 if (*pi_balance) { /* right branch has grown longer */ 00219 dprintk("MORE: right branch has grown"); 00220 00221 switch ((*ppr)->tree_b) { 00222 case -1: 00223 dprintk("MORE: balance was off, fixed implicitly"); 00224 (*ppr)->tree_b = 0; 00225 *pi_balance = FALSE; 00226 break; 00227 case 0: 00228 dprintk("MORE: balance was okay, now off but ok"); 00229 (*ppr)->tree_b = 1; 00230 break; 00231 case 1: 00232 dprintk("MORE: balance was off, need to rebalance"); 00233 p1 = (*ppr)->tree_r; 00234 if (p1->tree_b == 1) { /* RR */ 00235 dprintk("MORE: single RR"); 00236 (*ppr)->tree_r = p1->tree_l; 00237 p1->tree_l = *ppr; 00238 (*ppr)->tree_b = 0; 00239 *ppr = p1; 00240 } else { /* double RL */ 00241 dprintk("MORE: double RL"); 00242 00243 p2 = p1->tree_l; 00244 p1->tree_l = p2->tree_r; 00245 p2->tree_r = p1; 00246 00247 (*ppr)->tree_r = p2->tree_l; 00248 p2->tree_l = *ppr; 00249 00250 if (p2->tree_b == 1) 00251 (*ppr)->tree_b = -1; 00252 else 00253 (*ppr)->tree_b = 0; 00254 00255 if (p2->tree_b == -1) 00256 p1->tree_b = 1; 00257 else 00258 p1->tree_b = 0; 00259 00260 *ppr = p2; 00261 } /*else */ 00262 (*ppr)->tree_b = 0; 00263 *pi_balance = FALSE; 00264 } /*switch */ 00265 } /*if */ 00266 EXITV; 00267 } 00268 00269 /*if */ 00270 /* not less, not more: this is the same key! replace... 00271 */ 00272 dprintk("I found it! Replacing data value"); 00273 *pi_balance = FALSE; 00274 if (pfv_delete) 00275 (*pfv_delete) ((*ppr)->tree_p); 00276 (*ppr)->tree_p = p_data; 00277 EXITV; 00278 }
Definition at line 91 of file tree.c.
References ENTER, EXIT, and FALSE.
00093 { 00094 int i_balance = FALSE, i_uar_called = FALSE; 00095 00096 ENTER("tree_delete"); 00097 EXIT(delete(ppr_p, pfi_compare, p_user, pfv_uar, &i_balance, 00098 &i_uar_called)); 00099 } int tree_trav(tree ** ppr_tree, int (*pfi_uar) ( /* ??? */ ))
void tree_init | ( | tree ** | ppr_tree | ) |
void tree_mung | ( | tree ** | ppr_tree, | |
void(*)() | pfv_uar | |||
) |
Definition at line 114 of file tree.c.
References ENTER, EXITV, and tree_mung().
00115 { 00116 ENTER("tree_mung"); 00117 if (*ppr_tree) { 00118 tree_mung(&(**ppr_tree).tree_l, pfv_uar); 00119 tree_mung(&(**ppr_tree).tree_r, pfv_uar); 00120 if (pfv_uar) 00121 (*pfv_uar) ((**ppr_tree).tree_p); 00122 free(*ppr_tree); 00123 *ppr_tree = NULL; 00124 } 00125 EXITV; 00126 }
Definition at line 55 of file tree.c.
References ENTER, EXIT, i_comp(), and tree_srch().
00057 { 00058 register int i_comp; 00059 00060 ENTER("tree_srch"); 00061 00062 if (*ppr_tree) { 00063 i_comp = (*pfi_compare) (p_user, (**ppr_tree).tree_p); 00064 if (i_comp > 0) 00065 EXIT(tree_srch(&(**ppr_tree).tree_r, pfi_compare, p_user)); 00066 if (i_comp < 0) 00067 EXIT(tree_srch(&(**ppr_tree).tree_l, pfi_compare, p_user)); 00068 00069 /* not higher, not lower... this must be the one. 00070 */ 00071 EXIT((**ppr_tree).tree_p); 00072 } 00073 00074 /* grounded. NOT found. 00075 */ 00076 EXIT(NULL); 00077 }
int tree_trav | ( | tree ** | ppr_tree, | |
int(*)() | pfi_uar | |||
) |
Definition at line 99 of file tree.c.
00100 { 00101 ENTER("tree_trav"); 00102 00103 if (!*ppr_tree) 00104 EXIT(TRUE); 00105 00106 if (!tree_trav(&(**ppr_tree).tree_l, pfi_uar)) 00107 EXIT(FALSE); 00108 if (!(*pfi_uar) ((**ppr_tree).tree_p)) 00109 EXIT(FALSE); 00110 if (!tree_trav(&(**ppr_tree).tree_r, pfi_uar)) 00111 EXIT(FALSE); 00112 EXIT(TRUE); 00113 }