diff options
author | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2004-06-22 04:01:52 +0000 |
---|---|---|
committer | Anil Madhavapeddy <avsm@cvs.openbsd.org> | 2004-06-22 04:01:52 +0000 |
commit | 07f9a9d13ea0b7f12cf124c7c25c9b01c96c9369 (patch) | |
tree | 63b3492941bfdd52a92247669895596bbb90b758 /gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c | |
parent | 48e173e619472dce9fa16a21cb6fb6ac6a9e3d24 (diff) |
update to lynx 2.8.5rel.1
tested todd@,naddy@. millert@ deraadt@ ok
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c')
-rw-r--r-- | gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c | 648 |
1 files changed, 336 insertions, 312 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c index db3b50db510..ca03df51778 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTBTree.c @@ -20,7 +20,7 @@ PUBLIC HTBTree * HTBTree_new ARGS1(HTComparer, comp) ** for it when given a mean to compare things */ { - HTBTree * tree = (HTBTree *)malloc(sizeof(HTBTree)); + HTBTree * tree = typeMalloc(HTBTree); if (tree==NULL) outofmem(__FILE__, "HTBTree_new"); tree->compare = comp; @@ -38,7 +38,7 @@ PRIVATE void HTBTElement_free ARGS1(HTBTElement*, element) */ { if (element) { - if (element->left != NULL) + if (element->left != NULL) HTBTElement_free(element->left); if (element->right != NULL) HTBTElement_free(element->right); @@ -64,7 +64,7 @@ PRIVATE void HTBTElementAndObject_free ARGS1(HTBTElement*, element) */ { if (element) { /* Just in case nothing was in the tree anyway */ - if (element->left != NULL) + if (element->left != NULL) HTBTElementAndObject_free(element->left); if (element->right != NULL) HTBTElementAndObject_free(element->right); @@ -83,6 +83,30 @@ PUBLIC void HTBTreeAndObject_free ARGS1(HTBTree*, tree) } +PUBLIC void * HTBTree_search ARGS2( + HTBTree*, tree, + void*, object) + /********************************************************************** + ** Returns a pointer to equivalent object in a tree or NULL if none. + */ +{ + HTBTElement * cur = tree->top; + int res; + + while (cur != NULL) + { + res = tree->compare(object, cur->object); + + if (res == 0) + return cur->object; + else if (res < 0) + cur = cur->left; + else if (res > 0) + cur = cur->right; + } + return NULL; +} + PUBLIC void HTBTree_add ARGS2( @@ -91,7 +115,7 @@ PUBLIC void HTBTree_add ARGS2( /********************************************************************** ** This void is the core of HTBTree.c . It will ** 1/ add a new element to the tree at the right place - ** so that the tree remains sorted + ** so that the tree remains sorted ** 2/ balance the tree to be as fast as possible when reading it */ { @@ -101,27 +125,27 @@ PUBLIC void HTBTree_add ARGS2( HTBTElement * father_of_forefather; BOOL father_found,top_found; int depth,depth2,corrections; - /* father_of_element is a pointer to the structure that is the father of the - ** new object "object". - ** added_element is a pointer to the structure that contains or will contain - ** the new object "object". - ** father_of_forefather and forefather_of_element are pointers that are used - ** to modify the depths of upper elements, when needed. - ** - ** father_found indicates by a value NO when the future father of "object" - ** is found. - ** top_found indicates by a value NO when, in case of a difference of depths - ** < 2, the top of the tree is encountered and forbids any further try to - ** balance the tree. - ** corrections is an integer used to avoid infinite loops in cases - ** such as: - ** - ** 3 3 - ** 4 4 - ** 5 5 - ** - ** 3 is used here to show that it need not be the top of the tree. - */ + /* father_of_element is a pointer to the structure that is the father of the + ** new object "object". + ** added_element is a pointer to the structure that contains or will contain + ** the new object "object". + ** father_of_forefather and forefather_of_element are pointers that are used + ** to modify the depths of upper elements, when needed. + ** + ** father_found indicates by a value NO when the future father of "object" + ** is found. + ** top_found indicates by a value NO when, in case of a difference of depths + ** < 2, the top of the tree is encountered and forbids any further try to + ** balance the tree. + ** corrections is an integer used to avoid infinite loops in cases + ** such as: + ** + ** 3 3 + ** 4 4 + ** 5 5 + ** + ** 3 is used here to show that it need not be the top of the tree. + */ /* ** 1/ Adding of the element to the binary tree @@ -129,124 +153,124 @@ PUBLIC void HTBTree_add ARGS2( if (tree->top == NULL) { - tree->top = (HTBTElement *)malloc(sizeof(HTBTElement)); - if (tree->top == NULL) outofmem(__FILE__, "HTBTree_add"); - tree->top->up = NULL; - tree->top->object = object; - tree->top->left = NULL; - tree->top->left_depth = 0; - tree->top->right = NULL; - tree->top->right_depth = 0; + tree->top = typeMalloc(HTBTElement); + if (tree->top == NULL) outofmem(__FILE__, "HTBTree_add"); + tree->top->up = NULL; + tree->top->object = object; + tree->top->left = NULL; + tree->top->left_depth = 0; + tree->top->right = NULL; + tree->top->right_depth = 0; } else { - father_found = YES; - father_of_element = tree->top; - added_element = NULL; - father_of_forefather = NULL; - forefather_of_element = NULL; - while (father_found) - { - if (tree->compare(object,father_of_element->object)<0) + father_found = YES; + father_of_element = tree->top; + added_element = NULL; + father_of_forefather = NULL; + forefather_of_element = NULL; + while (father_found) + { + int res = tree->compare(object,father_of_element->object); + if (res < 0) { - if (father_of_element->left != NULL) - father_of_element = father_of_element->left; - else - { - father_found = NO; - father_of_element->left = - (HTBTElement *)malloc(sizeof(HTBTElement)); - if (father_of_element->left==NULL) - outofmem(__FILE__, "HTBTree_add"); - added_element = father_of_element->left; - added_element->up = father_of_element; - added_element->object = object; - added_element->left = NULL; - added_element->left_depth = 0; - added_element->right = NULL; - added_element->right_depth = 0; - } - } - if (tree->compare(object,father_of_element->object)>=0) - { - if (father_of_element->right != NULL) - father_of_element = father_of_element->right; - else - { - father_found = NO; - father_of_element->right = - (HTBTElement *)malloc(sizeof(HTBTElement)); - if (father_of_element->right==NULL) - outofmem(__FILE__, "HTBTree_add"); - added_element = father_of_element->right; - added_element->up = father_of_element; - added_element->object = object; - added_element->left = NULL; - added_element->left_depth = 0; - added_element->right = NULL; - added_element->right_depth = 0; - } - } + if (father_of_element->left != NULL) + father_of_element = father_of_element->left; + else + { + father_found = NO; + father_of_element->left = typeMalloc(HTBTElement); + if (father_of_element->left==NULL) + outofmem(__FILE__, "HTBTree_add"); + added_element = father_of_element->left; + added_element->up = father_of_element; + added_element->object = object; + added_element->left = NULL; + added_element->left_depth = 0; + added_element->right = NULL; + added_element->right_depth = 0; + } + } + else /* res >= 0 */ + { + if (father_of_element->right != NULL) + father_of_element = father_of_element->right; + else + { + father_found = NO; + father_of_element->right = typeMalloc(HTBTElement); + if (father_of_element->right==NULL) + outofmem(__FILE__, "HTBTree_add"); + added_element = father_of_element->right; + added_element->up = father_of_element; + added_element->object = object; + added_element->left = NULL; + added_element->left_depth = 0; + added_element->right = NULL; + added_element->right_depth = 0; + } + } } - /* - ** Changing of all depths that need to be changed - */ - father_of_forefather = father_of_element; - forefather_of_element = added_element; - do - { - if (father_of_forefather->left == forefather_of_element) - { - depth = father_of_forefather->left_depth; - father_of_forefather->left_depth = 1 - + MAXIMUM(forefather_of_element->right_depth, - forefather_of_element->left_depth); - depth2 = father_of_forefather->left_depth; - } - else + + /* + ** Changing of all depths that need to be changed + */ + father_of_forefather = father_of_element; + forefather_of_element = added_element; + do + { + if (father_of_forefather->left == forefather_of_element) { - depth = father_of_forefather->right_depth; - father_of_forefather->right_depth = 1 - + MAXIMUM(forefather_of_element->right_depth, - forefather_of_element->left_depth); - depth2 = father_of_forefather->right_depth; - } - forefather_of_element = father_of_forefather; - father_of_forefather = father_of_forefather->up; - } while ((depth != depth2) && (father_of_forefather != NULL)); - - - - /* - ** 2/ Balancing the binary tree, if necessary - */ - top_found = YES; - corrections = 0; - while ((top_found) && (corrections < 7)) - { - if ((abs(father_of_element->left_depth - - father_of_element->right_depth)) < 2) + depth = father_of_forefather->left_depth; + father_of_forefather->left_depth = 1 + + MAXIMUM(forefather_of_element->right_depth, + forefather_of_element->left_depth); + depth2 = father_of_forefather->left_depth; + } + else + { + depth = father_of_forefather->right_depth; + father_of_forefather->right_depth = 1 + + MAXIMUM(forefather_of_element->right_depth, + forefather_of_element->left_depth); + depth2 = father_of_forefather->right_depth; + } + forefather_of_element = father_of_forefather; + father_of_forefather = father_of_forefather->up; + } while ((depth != depth2) && (father_of_forefather != NULL)); + + + + /* + ** 2/ Balancing the binary tree, if necessary + */ + top_found = YES; + corrections = 0; + while ((top_found) && (corrections < 7)) + { + if ((abs(father_of_element->left_depth + - father_of_element->right_depth)) < 2) { - if (father_of_element->up != NULL) - father_of_element = father_of_element->up; - else top_found = NO; + if (father_of_element->up != NULL) + father_of_element = father_of_element->up; + else top_found = NO; } - else - { /* We start the process of balancing */ - - corrections = corrections + 1; - /* - ** corrections is an integer used to avoid infinite - ** loops in cases such as: - ** - ** 3 3 - ** 4 4 - ** 5 5 - ** - ** 3 is used to show that it need not be the top of the tree - ** But let's avoid these two exceptions anyhow - ** with the two following conditions (4 March 94 - AS) - */ + else + { /* We start the process of balancing */ + + corrections = corrections + 1; + /* + ** corrections is an integer used to avoid infinite + ** loops in cases such as: + ** + ** 3 3 + ** 4 4 + ** 5 5 + ** + ** 3 is used to show that it need not be the top of the tree + ** But let's avoid these two exceptions anyhow + ** with the two following conditions (4 March 94 - AS) + */ if ((father_of_element->left == NULL) && (father_of_element->right->right == NULL) @@ -261,26 +285,26 @@ PUBLIC void HTBTree_add ARGS2( corrections = 7; - if (father_of_element->left_depth > father_of_element->right_depth) - { - added_element = father_of_element->left; - father_of_element->left_depth = added_element->right_depth; - added_element->right_depth = 1 - + MAXIMUM(father_of_element->right_depth, - father_of_element->left_depth); - if (father_of_element->up != NULL) + if (father_of_element->left_depth > father_of_element->right_depth) + { + added_element = father_of_element->left; + father_of_element->left_depth = added_element->right_depth; + added_element->right_depth = 1 + + MAXIMUM(father_of_element->right_depth, + father_of_element->left_depth); + if (father_of_element->up != NULL) { /* Bug fixed in March 94 - AS */ BOOL first_time; - father_of_forefather = father_of_element->up; - forefather_of_element = added_element; + father_of_forefather = father_of_element->up; + forefather_of_element = added_element; first_time = YES; - do - { - if (father_of_forefather->left - == forefather_of_element->up) - { + do + { + if (father_of_forefather->left + == forefather_of_element->up) + { depth = father_of_forefather->left_depth; if (first_time) { @@ -294,11 +318,11 @@ PUBLIC void HTBTree_add ARGS2( + MAXIMUM(forefather_of_element->up->left_depth, forefather_of_element->up->right_depth); - depth2 = father_of_forefather->left_depth; + depth2 = father_of_forefather->left_depth; } - else + else { - depth = father_of_forefather->right_depth; + depth = father_of_forefather->right_depth; if (first_time) { father_of_forefather->right_depth = 1 @@ -310,100 +334,100 @@ PUBLIC void HTBTree_add ARGS2( father_of_forefather->right_depth = 1 + MAXIMUM(forefather_of_element->up->left_depth, forefather_of_element->up->right_depth); - depth2 = father_of_forefather->right_depth; + depth2 = father_of_forefather->right_depth; } - forefather_of_element = forefather_of_element->up; - father_of_forefather = father_of_forefather->up; + forefather_of_element = forefather_of_element->up; + father_of_forefather = father_of_forefather->up; } while ((depth != depth2) && (father_of_forefather != NULL)); - father_of_forefather = father_of_element->up; - if (father_of_forefather->left == father_of_element) - { - /* - ** 3 3 - ** 4 5 - ** When tree 5 6 becomes 7 4 - ** 7 8 8 6 - ** - ** 3 is used to show that it may not be the top of the - ** tree. - */ - father_of_forefather->left = added_element; - father_of_element->left = added_element->right; - added_element->right = father_of_element; - } - if (father_of_forefather->right == father_of_element) - { - /* - ** 3 3 - ** 4 5 - ** When tree 5 6 becomes 7 4 - ** 7 8 8 6 - ** - ** 3 is used to show that it may not be the top of the - ** tree - */ - father_of_forefather->right = added_element; - father_of_element->left = added_element->right; - added_element->right = father_of_element; - } - added_element->up = father_of_forefather; + father_of_forefather = father_of_element->up; + if (father_of_forefather->left == father_of_element) + { + /* + ** 3 3 + ** 4 5 + ** When tree 5 6 becomes 7 4 + ** 7 8 8 6 + ** + ** 3 is used to show that it may not be the top of the + ** tree. + */ + father_of_forefather->left = added_element; + father_of_element->left = added_element->right; + added_element->right = father_of_element; + } + if (father_of_forefather->right == father_of_element) + { + /* + ** 3 3 + ** 4 5 + ** When tree 5 6 becomes 7 4 + ** 7 8 8 6 + ** + ** 3 is used to show that it may not be the top of the + ** tree + */ + father_of_forefather->right = added_element; + father_of_element->left = added_element->right; + added_element->right = father_of_element; + } + added_element->up = father_of_forefather; } - else + else { - /* - ** - ** 1 2 - ** When tree 2 3 becomes 4 1 - ** 4 5 5 3 - ** - ** 1 is used to show that it is the top of the tree - */ - added_element->up = NULL; - father_of_element->left = added_element->right; - added_element->right = father_of_element; + /* + ** + ** 1 2 + ** When tree 2 3 becomes 4 1 + ** 4 5 5 3 + ** + ** 1 is used to show that it is the top of the tree + */ + added_element->up = NULL; + father_of_element->left = added_element->right; + added_element->right = father_of_element; } - father_of_element->up = added_element; - if (father_of_element->left != NULL) - father_of_element->left->up = father_of_element; - } - else - { - added_element = father_of_element->right; - father_of_element->right_depth = added_element->left_depth; - added_element->left_depth = 1 + - MAXIMUM(father_of_element->right_depth, - father_of_element->left_depth); - if (father_of_element->up != NULL) + father_of_element->up = added_element; + if (father_of_element->left != NULL) + father_of_element->left->up = father_of_element; + } + else + { + added_element = father_of_element->right; + father_of_element->right_depth = added_element->left_depth; + added_element->left_depth = 1 + + MAXIMUM(father_of_element->right_depth, + father_of_element->left_depth); + if (father_of_element->up != NULL) /* Bug fixed in March 94 - AS */ { BOOL first_time; - father_of_forefather = father_of_element->up; - forefather_of_element = added_element; + father_of_forefather = father_of_element->up; + forefather_of_element = added_element; first_time = YES; - do - { - if (father_of_forefather->left + do + { + if (father_of_forefather->left == forefather_of_element->up) - { - depth = father_of_forefather->left_depth; - if (first_time) + { + depth = father_of_forefather->left_depth; + if (first_time) { father_of_forefather->left_depth = 1 + MAXIMUM(forefather_of_element->left_depth, forefather_of_element->right_depth); first_time = NO; } - else + else father_of_forefather->left_depth = 1 + MAXIMUM(forefather_of_element->up->left_depth, - forefather_of_element->up->right_depth); + forefather_of_element->up->right_depth); depth2 = father_of_forefather->left_depth; } - else + else { - depth = father_of_forefather->right_depth; + depth = father_of_forefather->right_depth; if (first_time) { father_of_forefather->right_depth = 1 @@ -415,78 +439,78 @@ PUBLIC void HTBTree_add ARGS2( father_of_forefather->right_depth = 1 + MAXIMUM(forefather_of_element->up->left_depth, forefather_of_element->up->right_depth); - depth2 = father_of_forefather->right_depth; + depth2 = father_of_forefather->right_depth; } - father_of_forefather = father_of_forefather->up; - forefather_of_element = forefather_of_element->up; + father_of_forefather = father_of_forefather->up; + forefather_of_element = forefather_of_element->up; } while ((depth != depth2) && (father_of_forefather != NULL)); - father_of_forefather = father_of_element->up; - if (father_of_forefather->left == father_of_element) - { - /* - ** 3 3 - ** 4 6 - ** When tree 5 6 becomes 4 8 - ** 7 8 5 7 - ** - ** 3 is used to show that it may not be the top of the - ** tree. - */ - father_of_forefather->left = added_element; - father_of_element->right = added_element->left; - added_element->left = father_of_element; - } - if (father_of_forefather->right == father_of_element) - { - /* - ** 3 3 - ** 4 6 - ** When tree 5 6 becomes 4 8 - ** 7 8 5 7 - ** - ** 3 is used to show that it may not be the top of the - ** tree - */ - father_of_forefather->right = added_element; - father_of_element->right = added_element->left; - added_element->left = father_of_element; - } - added_element->up = father_of_forefather; + father_of_forefather = father_of_element->up; + if (father_of_forefather->left == father_of_element) + { + /* + ** 3 3 + ** 4 6 + ** When tree 5 6 becomes 4 8 + ** 7 8 5 7 + ** + ** 3 is used to show that it may not be the top of the + ** tree. + */ + father_of_forefather->left = added_element; + father_of_element->right = added_element->left; + added_element->left = father_of_element; + } + if (father_of_forefather->right == father_of_element) + { + /* + ** 3 3 + ** 4 6 + ** When tree 5 6 becomes 4 8 + ** 7 8 5 7 + ** + ** 3 is used to show that it may not be the top of the + ** tree + */ + father_of_forefather->right = added_element; + father_of_element->right = added_element->left; + added_element->left = father_of_element; + } + added_element->up = father_of_forefather; } - else - { - /* - ** - ** 1 3 - ** When tree 2 3 becomes 1 5 - ** 4 5 2 4 - ** - ** 1 is used to show that it is the top of the tree. - */ - added_element->up = NULL; - father_of_element->right = added_element->left; - added_element->left = father_of_element; + else + { + /* + ** + ** 1 3 + ** When tree 2 3 becomes 1 5 + ** 4 5 2 4 + ** + ** 1 is used to show that it is the top of the tree. + */ + added_element->up = NULL; + father_of_element->right = added_element->left; + added_element->left = father_of_element; } - father_of_element->up = added_element; - if (father_of_element->right != NULL) - father_of_element->right->up = father_of_element; + father_of_element->up = added_element; + if (father_of_element->right != NULL) + father_of_element->right->up = father_of_element; } } - } - while (father_of_element->up != NULL) + } + while (father_of_element->up != NULL) { - father_of_element = father_of_element->up; - } - tree->top = father_of_element; + father_of_element = father_of_element->up; + } + tree->top = father_of_element; } } PUBLIC HTBTElement * HTBTree_next ARGS2( - HTBTree*, tree, - HTBTElement*, ele) + HTBTree*, tree, + HTBTElement*, ele) /************************************************************************** ** this function returns a pointer to the leftmost element if ele is NULL, ** and to the next object to the right otherwise. @@ -498,30 +522,30 @@ PUBLIC HTBTElement * HTBTree_next ARGS2( if (ele == NULL) { - father_of_element = tree->top; - if (father_of_element != NULL) - while (father_of_element->left != NULL) - father_of_element = father_of_element->left; + father_of_element = tree->top; + if (father_of_element != NULL) + while (father_of_element->left != NULL) + father_of_element = father_of_element->left; } else { - father_of_element = ele; - if (father_of_element->right != NULL) + father_of_element = ele; + if (father_of_element->right != NULL) { - father_of_element = father_of_element->right; - while (father_of_element->left != NULL) - father_of_element = father_of_element->left; + father_of_element = father_of_element->right; + while (father_of_element->left != NULL) + father_of_element = father_of_element->left; } - else + else { - father_of_forefather = father_of_element->up; - while (father_of_forefather && + father_of_forefather = father_of_element->up; + while (father_of_forefather && (father_of_forefather->right == father_of_element)) - { - father_of_element = father_of_forefather; + { + father_of_element = father_of_forefather; father_of_forefather = father_of_element->up; } - father_of_element = father_of_forefather; + father_of_element = father_of_forefather; } } #ifdef BTREE_TRACE @@ -530,22 +554,22 @@ PUBLIC HTBTElement * HTBTree_next ARGS2( */ if (father_of_element != NULL) { - printf("\nObject = %s\t",(char *)father_of_element->object); - if (father_of_element->up != NULL) - printf("Objet du pere = %s\n", + printf("\nObject = %s\t",(char *)father_of_element->object); + if (father_of_element->up != NULL) + printf("Objet du pere = %s\n", (char *)father_of_element->up->object); - else printf("Pas de Pere\n"); - if (father_of_element->left != NULL) - printf("Objet du fils gauche = %s\t", + else printf("Pas de Pere\n"); + if (father_of_element->left != NULL) + printf("Objet du fils gauche = %s\t", (char *)father_of_element->left->object); - else printf("Pas de fils gauche\t"); - if (father_of_element->right != NULL) - printf("Objet du fils droit = %s\n", + else printf("Pas de fils gauche\t"); + if (father_of_element->right != NULL) + printf("Objet du fils droit = %s\n", (char *)father_of_element->right->object); - else printf("Pas de fils droit\n"); - printf("Profondeur gauche = %d\t",father_of_element->left_depth); - printf("Profondeur droite = %d\n",father_of_element->right_depth); - printf(" **************\n"); + else printf("Pas de fils droit\n"); + printf("Profondeur gauche = %d\t",father_of_element->left_depth); + printf("Profondeur droite = %d\n",father_of_element->right_depth); + printf(" **************\n"); } #endif return father_of_element; @@ -702,9 +726,9 @@ main () while (next_element != NULL) { #ifndef BTREE_TRACE - printf("The next element is %s\n",next_element->object); + printf("The next element is %s\n",next_element->object); #endif - next_element = HTBTree_next(tree,next_element); + next_element = HTBTree_next(tree,next_element); } HTBTree_free(tree); } |