diff options
Diffstat (limited to 'avl-1.4.0/avl.c')
-rw-r--r-- | avl-1.4.0/avl.c | 1154 |
1 files changed, 0 insertions, 1154 deletions
diff --git a/avl-1.4.0/avl.c b/avl-1.4.0/avl.c deleted file mode 100644 index 82cdb6e..0000000 --- a/avl-1.4.0/avl.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* libavl - manipulates AVL trees. - Copyright (C) 1998, 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - - The author may be contacted at <pfaffben@pilot.msu.edu> on the - Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA - through more mundane means. */ - -/* This is file avl.c in libavl. */ - -#if HAVE_CONFIG_H -#include <config.h> -#endif -#if PSPP -#include "common.h" -#include "arena.h" -#define HAVE_XMALLOC 1 -#endif -#if SELF_TEST -#include <limits.h> -#include <time.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include "avl.h" - -#if !PSPP && !__GCC__ -#define inline -#endif - -#if !PSPP -#if __GNUC__ >= 2 -#define unused __attribute__ ((unused)) -#else -#define unused -#endif -#endif - -#ifdef HAVE_XMALLOC -void *xmalloc (size_t); -#else /* !HAVE_XMALLOC */ -/* Allocates SIZE bytes of space using malloc(). Aborts if out of - memory. */ -static void * -xmalloc (size_t size) -{ - void *vp; - - if (size == 0) - return NULL; - vp = malloc (size); - - assert (vp != NULL); - if (vp == NULL) - { - fprintf (stderr, "virtual memory exhausted\n"); - exit (EXIT_FAILURE); - } - return vp; -} -#endif /* !HAVE_XMALLOC */ - -/* Creates an AVL tree in arena OWNER (which can be NULL). The arena - is owned by the caller, not by the AVL tree. CMP is a order - function for the data to be stored in the tree. PARAM is arbitrary - data that becomes an argument to the comparison function. */ -avl_tree * -avl_create (MAYBE_ARENA avl_comparison_func cmp, void *param) -{ - avl_tree *tree; - - assert (cmp != NULL); -#if PSPP - if (owner) - tree = arena_alloc (owner, sizeof (avl_tree)); - else -#endif - tree = xmalloc (sizeof (avl_tree)); - -#if PSPP - tree->owner = owner; -#endif - tree->root.link[0] = NULL; - tree->root.link[1] = NULL; - tree->cmp = cmp; - tree->count = 0; - tree->param = param; - - return tree; -} - -/* Destroy tree TREE. Function FREE_FUNC is called for every node in - the tree as it is destroyed. - - No effect if the tree has an arena owner and free_func is NULL. - The caller owns the arena and must destroy it itself. - - Do not attempt to reuse the tree after it has been freed. Create a - new one. */ -void -avl_destroy (avl_tree *tree, avl_node_func free_func) -{ - assert (tree != NULL); - -#if PSPP - if (free_func || tree->owner == NULL) -#endif - { - /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13 - (postorder traversal). */ - - /* T1. */ - avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ - char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */ - int ap = 0; /* Stack A: height. */ - avl_node *p = tree->root.link[0]; - - for (;;) - { - /* T2. */ - while (p != NULL) - { - /* T3. */ - ab[ap] = 0; - an[ap++] = p; - p = p->link[0]; - } - - /* T4. */ - for (;;) - { - if (ap == 0) - goto done; - - p = an[--ap]; - if (ab[ap] == 0) - { - ab[ap++] = 1; - p = p->link[1]; - break; - } - - if (free_func) - free_func (p->data, tree->param); -#if PSPP - if (tree->owner == NULL) -#endif - free (p); - } - } - } - - done: -#if PSPP - if (tree->owner == NULL) -#endif - free (tree); -} - -/* avl_destroy() with FREE_FUNC hardcoded as free(). */ -void -avl_free (avl_tree *tree) -{ - avl_destroy (tree, (avl_node_func) free); -} - -/* Return the number of nodes in TREE. */ -int -avl_count (const avl_tree *tree) -{ - assert (tree != NULL); - return tree->count; -} - -/* Allocates room for a new avl_node in arena OWNER, or using - xmalloc() if OWNER is NULL. */ -#if PSPP -static inline avl_node * -new_node (arena **owner) -{ - if (owner != NULL) - return arena_alloc (owner, sizeof (avl_node)); - else - return xmalloc (sizeof (avl_node)); -} -#else -static inline avl_node * -new_node (void) -{ - return xmalloc (sizeof (avl_node)); -} - -#define new_node(owner) \ - new_node () -#endif - -/* Copy the contents of TREE to a new tree in arena OWNER. If COPY is - non-NULL, then each data item is passed to function COPY, and the - return values are inserted into the new tree; otherwise, the items - are copied verbatim from the old tree to the new tree. Returns the - new tree. */ -avl_tree * -avl_copy (MAYBE_ARENA const avl_tree *tree, avl_copy_func copy) -{ - /* This is a combination of Knuth's Algorithm 2.3.1C (copying a - binary tree) and Algorithm 2.3.1T as modified by exercise 12 - (preorder traversal). */ - - avl_tree *new_tree; - - /* PT1. */ - const avl_node *pa[AVL_MAX_HEIGHT]; /* Stack PA: nodes. */ - const avl_node **pp = pa; /* Stack PA: stack pointer. */ - const avl_node *p = &tree->root; - - /* QT1. */ - avl_node *qa[AVL_MAX_HEIGHT]; /* Stack QA: nodes. */ - avl_node **qp = qa; /* Stack QA: stack pointer. */ - avl_node *q; - - assert (tree != NULL); -#if PSPP - new_tree = avl_create (owner, tree->cmp, tree->param); -#else - new_tree = avl_create (tree->cmp, tree->param); -#endif - new_tree->count = tree->count; - q = &new_tree->root; - - for (;;) - { - /* C4. */ - if (p->link[0] != NULL) - { - avl_node *r = new_node (owner); - r->link[0] = r->link[1] = NULL; - q->link[0] = r; - } - - /* C5: Find preorder successors of P and Q. */ - goto start; - for (;;) - { - /* PT2. */ - while (p != NULL) - { - goto escape; - start: - /* PT3. */ - *pp++ = p; - *qp++ = q; - p = p->link[0]; - q = q->link[0]; - } - - /* PT4. */ - if (pp == pa) - { - assert (qp == qa); - return new_tree; - } - - p = *--pp; - q = *--qp; - - /* PT5. */ - p = p->link[1]; - q = q->link[1]; - } - escape: - - /* C2. */ - if (p->link[1]) - { - avl_node *r = new_node (owner); - r->link[0] = r->link[1] = NULL; - q->link[1] = r; - } - - /* C3. */ - q->bal = p->bal; - if (copy == NULL) - q->data = p->data; - else - q->data = copy (p->data, tree->param); - } -} - -/* Walk tree TREE in inorder, calling WALK_FUNC at each node. Passes - PARAM to WALK_FUNC. */ -void -avl_walk (const avl_tree *tree, avl_node_func walk_func, void *param) -{ - /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ - assert (tree && walk_func); - - { - /* T1. */ - const avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */ - const avl_node **ap = an; /* Stack A: stack pointer. */ - const avl_node *p = tree->root.link[0]; - - for (;;) - { - /* T2. */ - while (p != NULL) - { - /* T3. */ - *ap++ = p; - p = p->link[0]; - } - - /* T4. */ - if (ap == an) - return; - p = *--ap; - - /* T5. */ - walk_func (p->data, param); - p = p->link[1]; - } - } -} - -/* Each call to this function for a given TREE and TRAV return the - next item in the tree in inorder. Initialize the first element of - TRAV (init) to 0 before calling the first time. Returns NULL when - out of elements. */ -void * -avl_traverse (const avl_tree *tree, avl_traverser *trav) -{ - assert (tree && trav); - - /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */ - if (trav->init == 0) - { - /* T1. */ - trav->init = 1; - trav->nstack = 0; - trav->p = tree->root.link[0]; - } - else - /* T5. */ - trav->p = trav->p->link[1]; - - for (;;) - { - /* T2. */ - while (trav->p != NULL) - { - /* T3. */ - trav->stack[trav->nstack++] = trav->p; - trav->p = trav->p->link[0]; - } - - /* T4. */ - if (trav->nstack == 0) - { - trav->init = 0; - return NULL; - } - trav->p = trav->stack[--trav->nstack]; - - /* T5. */ - return trav->p->data; - } -} - -/* Search TREE for an item matching ITEM. If found, returns a pointer - to the address of the item. If none is found, ITEM is inserted - into the tree, and a pointer to the address of ITEM is returned. - In either case, the pointer returned can be changed by the caller, - or the returned data item can be directly edited, but the key data - in the item must not be changed. */ -void ** -avl_probe (avl_tree *tree, void *item) -{ - /* Uses Knuth's Algorithm 6.2.3A (balanced tree search and - insertion), but caches results of comparisons. In empirical - tests this eliminates about 25% of the comparisons seen under - random insertions. */ - - /* A1. */ - avl_node *t; - avl_node *s, *p, *q, *r; - - assert (tree != NULL); - t = &tree->root; - s = p = t->link[0]; - - if (s == NULL) - { - tree->count++; - assert (tree->count == 1); - q = t->link[0] = new_node (tree->owner); - q->data = item; - q->link[0] = q->link[1] = NULL; - q->bal = 0; - return &q->data; - } - - for (;;) - { - /* A2. */ - int diff = tree->cmp (item, p->data, tree->param); - - /* A3. */ - if (diff < 0) - { - p->cache = 0; - q = p->link[0]; - if (q == NULL) - { - p->link[0] = q = new_node (tree->owner); - break; - } - } - /* A4. */ - else if (diff > 0) - { - p->cache = 1; - q = p->link[1]; - if (q == NULL) - { - p->link[1] = q = new_node (tree->owner); - break; - } - } - else - /* A2. */ - return &p->data; - - /* A3, A4. */ - if (q->bal != 0) - t = p, s = q; - p = q; - } - - /* A5. */ - tree->count++; - q->data = item; - q->link[0] = q->link[1] = NULL; - q->bal = 0; - - /* A6. */ - r = p = s->link[(int) s->cache]; - while (p != q) - { - p->bal = p->cache * 2 - 1; - p = p->link[(int) p->cache]; - } - - /* A7. */ - if (s->cache == 0) - { - /* a = -1. */ - if (s->bal == 0) - { - s->bal = -1; - return &q->data; - } - else if (s->bal == +1) - { - s->bal = 0; - return &q->data; - } - - assert (s->bal == -1); - if (r->bal == -1) - { - /* A8. */ - p = r; - s->link[0] = r->link[1]; - r->link[1] = s; - s->bal = r->bal = 0; - } - else - { - /* A9. */ - assert (r->bal == +1); - p = r->link[1]; - r->link[1] = p->link[0]; - p->link[0] = r; - s->link[0] = p->link[1]; - p->link[1] = s; - if (p->bal == -1) - s->bal = 1, r->bal = 0; - else if (p->bal == 0) - s->bal = r->bal = 0; - else - { - assert (p->bal == +1); - s->bal = 0, r->bal = -1; - } - p->bal = 0; - } - } - else - { - /* a == +1. */ - if (s->bal == 0) - { - s->bal = 1; - return &q->data; - } - else if (s->bal == -1) - { - s->bal = 0; - return &q->data; - } - - assert (s->bal == +1); - if (r->bal == +1) - { - /* A8. */ - p = r; - s->link[1] = r->link[0]; - r->link[0] = s; - s->bal = r->bal = 0; - } - else - { - /* A9. */ - assert (r->bal == -1); - p = r->link[0]; - r->link[0] = p->link[1]; - p->link[1] = r; - s->link[1] = p->link[0]; - p->link[0] = s; - if (p->bal == +1) - s->bal = -1, r->bal = 0; - else if (p->bal == 0) - s->bal = r->bal = 0; - else - { - assert (p->bal == -1); - s->bal = 0, r->bal = 1; - } - p->bal = 0; - } - } - - /* A10. */ - if (t != &tree->root && s == t->link[1]) - t->link[1] = p; - else - t->link[0] = p; - - return &q->data; -} - -/* Search TREE for an item matching ITEM, and return it if found. */ -void * -avl_find (const avl_tree *tree, const void *item) -{ - const avl_node *p; - - assert (tree != NULL); - for (p = tree->root.link[0]; p; ) - { - int diff = tree->cmp (item, p->data, tree->param); - - if (diff < 0) - p = p->link[0]; - else if (diff > 0) - p = p->link[1]; - else - return p->data; - } - - return NULL; -} - -/* Search TREE for an item close to the value of ITEM, and return it. - This function will return a null pointer only if TREE is empty. */ -void * -avl_find_close (const avl_tree *tree, const void *item) -{ - const avl_node *p; - - assert (tree != NULL); - p = tree->root.link[0]; - if (p == NULL) - return NULL; - - for (;;) - { - int diff = tree->cmp (item, p->data, tree->param); - int t; - - if (diff < 0) - t = 0; - else if (diff > 0) - t = 1; - else - return p->data; - - if (p->link[t]) - p = p->link[t]; - else - return p->data; - } -} - -/* Searches AVL tree TREE for an item matching ITEM. If found, the - item is removed from the tree and the actual item found is returned - to the caller. If no item matching ITEM exists in the tree, - returns NULL. */ -void * -avl_delete (avl_tree *tree, const void *item) -{ - /* Uses my Algorithm D, which can be found at - http://www.msu.edu/user/pfaffben/avl. Algorithm D is based on - Knuth's Algorithm 6.2.2D (Tree deletion) and 6.2.3A (Balanced - tree search and insertion), as well as the notes on pages 465-466 - of Vol. 3. */ - - /* D1. */ - avl_node *pa[AVL_MAX_HEIGHT]; /* Stack P: Nodes. */ - char a[AVL_MAX_HEIGHT]; /* Stack P: Bits. */ - int k = 1; /* Stack P: Pointer. */ - - avl_node **q; - avl_node *p; - - assert (tree != NULL); - - a[0] = 0; - pa[0] = &tree->root; - p = tree->root.link[0]; - for (;;) - { - /* D2. */ - int diff; - - if (p == NULL) - return NULL; - - diff = tree->cmp (item, p->data, tree->param); - if (diff == 0) - break; - - /* D3, D4. */ - pa[k] = p; - if (diff < 0) - { - p = p->link[0]; - a[k] = 0; - } - else if (diff > 0) - { - p = p->link[1]; - a[k] = 1; - } - k++; - } - tree->count--; - - item = p->data; - - /* D5. */ - q = &pa[k - 1]->link[(int) a[k - 1]]; - if (p->link[1] == NULL) - { - *q = p->link[0]; - if (*q) - (*q)->bal = 0; - } - else - { - /* D6. */ - avl_node *r = p->link[1]; - if (r->link[0] == NULL) - { - r->link[0] = p->link[0]; - *q = r; - r->bal = p->bal; - a[k] = 1; - pa[k++] = r; - } - else - { - /* D7. */ - avl_node *s = r->link[0]; - int l = k++; - - a[k] = 0; - pa[k++] = r; - - /* D8. */ - while (s->link[0] != NULL) - { - r = s; - s = r->link[0]; - a[k] = 0; - pa[k++] = r; - } - - /* D9. */ - a[l] = 1; - pa[l] = s; - s->link[0] = p->link[0]; - r->link[0] = s->link[1]; - s->link[1] = p->link[1]; - s->bal = p->bal; - *q = s; - } - } - -#if PSPP - if (tree->owner == NULL) -#endif - free (p); - - assert (k > 0); - /* D10. */ - while (--k) - { - avl_node *s = pa[k], *r; - - if (a[k] == 0) - { - /* D10. */ - if (s->bal == -1) - { - s->bal = 0; - continue; - } - else if (s->bal == 0) - { - s->bal = 1; - break; - } - - assert (s->bal == +1); - r = s->link[1]; - - assert (r != NULL); - if (r->bal == 0) - { - /* D11. */ - s->link[1] = r->link[0]; - r->link[0] = s; - r->bal = -1; - pa[k - 1]->link[(int) a[k - 1]] = r; - break; - } - else if (r->bal == +1) - { - /* D12. */ - s->link[1] = r->link[0]; - r->link[0] = s; - s->bal = r->bal = 0; - pa[k - 1]->link[(int) a[k - 1]] = r; - } - else - { - /* D13. */ - assert (r->bal == -1); - p = r->link[0]; - r->link[0] = p->link[1]; - p->link[1] = r; - s->link[1] = p->link[0]; - p->link[0] = s; - if (p->bal == +1) - s->bal = -1, r->bal = 0; - else if (p->bal == 0) - s->bal = r->bal = 0; - else - { - assert (p->bal == -1); - s->bal = 0, r->bal = +1; - } - p->bal = 0; - pa[k - 1]->link[(int) a[k - 1]] = p; - } - } - else - { - assert (a[k] == 1); - - /* D10. */ - if (s->bal == +1) - { - s->bal = 0; - continue; - } - else if (s->bal == 0) - { - s->bal = -1; - break; - } - - assert (s->bal == -1); - r = s->link[0]; - - if (r == NULL || r->bal == 0) - { - /* D11. */ - s->link[0] = r->link[1]; - r->link[1] = s; - r->bal = 1; - pa[k - 1]->link[(int) a[k - 1]] = r; - break; - } - else if (r->bal == -1) - { - /* D12. */ - s->link[0] = r->link[1]; - r->link[1] = s; - s->bal = r->bal = 0; - pa[k - 1]->link[(int) a[k - 1]] = r; - } - else if (r->bal == +1) - { - /* D13. */ - p = r->link[1]; - r->link[1] = p->link[0]; - p->link[0] = r; - s->link[0] = p->link[1]; - p->link[1] = s; - if (p->bal == -1) - s->bal = 1, r->bal = 0; - else if (p->bal == 0) - s->bal = r->bal = 0; - else - { - assert (p->bal == 1); - s->bal = 0, r->bal = -1; - } - p->bal = 0; - pa[k - 1]->link[(int) a[k - 1]] = p; - } - } - } - - return (void *) item; -} - -/* Inserts ITEM into TREE. Returns NULL if the item was inserted, - otherwise a pointer to the duplicate item. */ -void * -avl_insert (avl_tree *tree, void *item) -{ - void **p; - - assert (tree != NULL); - - p = avl_probe (tree, item); - return (*p == item) ? NULL : *p; -} - -/* If ITEM does not exist in TREE, inserts it and returns NULL. If a - matching item does exist, it is replaced by ITEM and the item - replaced is returned. The caller is responsible for freeing the - item returned. */ -void * -avl_replace (avl_tree *tree, void *item) -{ - void **p; - - assert (tree != NULL); - - p = avl_probe (tree, item); - if (*p == item) - return NULL; - else - { - void *r = *p; - *p = item; - return r; - } -} - -/* Delete ITEM from TREE when you know that ITEM must be in TREE. For - debugging purposes. */ -void * -(avl_force_delete) (avl_tree *tree, void *item) -{ - void *found = avl_delete (tree, item); - assert (found != NULL); - return found; -} - -#if SELF_TEST - -/* Used to flag delayed aborting. */ -int done = 0; - -/* Print the structure of node NODE of an avl tree, which is LEVEL - levels from the top of the tree. Uses different delimiters to - visually distinguish levels. */ -void -print_structure (avl_node *node, int level) -{ - char lc[] = "([{`/"; - char rc[] = ")]}'\\"; - - assert (level <= 10); - - if (node == NULL) - { - printf (" nil"); - return; - } - printf (" %c%d", lc[level % 5], (int) node->data); - if (node->link[0] || node->link[1]) - print_structure (node->link[0], level + 1); - if (node->link[1]) - print_structure (node->link[1], level + 1); - printf ("%c", rc[level % 5]); -} - -/* Compare two integers A and B and return a strcmp()-type result. */ -int -compare_ints (const void *a, const void *b, void *param unused) -{ - return ((int) a) - ((int) b); -} - -/* Print the value of integer A. */ -void -print_int (void *a, void *param unused) -{ - printf (" %d", (int) a); -} - -/* Linearly print contents of TREE. */ -void -print_contents (avl_tree *tree) -{ - avl_walk (tree, print_int, NULL); - printf ("\n"); -} - -/* Examine NODE in a avl tree. *COUNT is increased by the number of - nodes in the tree, including the current one. If the node is the - root of the tree, PARENT should be INT_MIN, otherwise it should be - the parent node value. DIR is the direction that the current node - is linked from the parent: -1 for left child, +1 for right child; - it is not used if PARENT is INT_MIN. Returns the height of the - tree rooted at NODE. */ -int -recurse_tree (avl_node *node, int *count, int parent, int dir) -{ - if (node) - { - int d = (int) node->data; - int nl = node->link[0] ? recurse_tree (node->link[0], count, d, -1) : 0; - int nr = node->link[1] ? recurse_tree (node->link[1], count, d, 1) : 0; - (*count)++; - - if (nr - nl != node->bal) - { - printf (" Node %d is unbalanced: right height=%d, left height=%d, " - "difference=%d, but balance factor=%d.\n", - d, nr, nl, nr - nl, node->bal); - done = 1; - } - - if (parent != INT_MIN) - { - assert (dir == -1 || dir == +1); - if (dir == -1 && d > parent) - { - printf (" Node %d is smaller than its left child %d.\n", - parent, d); - done = 1; - } - else if (dir == +1 && d < parent) - { - printf (" Node %d is larger than its right child %d.\n", - parent, d); - done = 1; - } - } - assert (node->bal >= -1 && node->bal <= 1); - return 1 + (nl > nr ? nl : nr); - } - else return 0; -} - -/* Check that everything about TREE is kosher. */ -void -verify_tree (avl_tree *tree) -{ - int count = 0; - recurse_tree (tree->root.link[0], &count, INT_MIN, 0); - if (count != tree->count) - { - printf (" Tree has %d nodes, but tree count is %d.\n", - count, tree->count); - done = 1; - } - if (done) - abort (); -} - -/* Arrange the N elements of ARRAY in random order. */ -void -shuffle (int *array, int n) -{ - int i; - - for (i = 0; i < n; i++) - { - int j = i + rand () % (n - i); - int t = array[j]; - array[j] = array[i]; - array[i] = t; - } -} - -/* Compares avl trees rooted at A and B, making sure that they are - identical. */ -void -compare_trees (avl_node *a, avl_node *b) -{ - if (a == NULL || b == NULL) - { - assert (a == NULL && b == NULL); - return; - } - if (a->data != b->data || a->bal != b->bal - || ((a->link[0] != NULL) ^ (b->link[0] != NULL)) - || ((a->link[1] != NULL) ^ (b->link[1] != NULL))) - { - printf (" Copied nodes differ: %d b=%d a->bal=%d b->bal=%d a:", - (int) a->data, (int) b->data, a->bal, b->bal); - if (a->link[0]) - printf ("l"); - if (a->link[1]) - printf ("r"); - printf (" b:"); - if (b->link[0]) - printf ("l"); - if (b->link[1]) - printf ("r"); - printf ("\n"); - abort (); - } - if (a->link[0] != NULL) - compare_trees (a->link[0], b->link[0]); - if (a->link[1] != NULL) - compare_trees (a->link[1], b->link[1]); -} - -/* Simple stress test procedure for the AVL tree routines. Does the - following: - - * Generate a random number seed. By default this is generated from - the current time. You can also pass a seed value on the command - line if you want to test the same case. The seed value is - displayed. - - * Create a tree and insert the integers from 0 up to TREE_SIZE - 1 - into it, in random order. Verify the tree structure after each - insertion. - - * Remove each integer from the tree, in a different random order. - After each deletion, verify the tree structure; also, make a copy - of the tree into a new tree, verify the copy and compare it to the - original, then destroy the copy. - - * Destroy the tree, increment the random seed value, and start over. - - If you make any modifications to the avl tree routines, then you - might want to insert some calls to print_structure() at strategic - places in order to be able to see what's really going on. Also, - memory debuggers like Checker or Purify are very handy. */ -#define TREE_SIZE 1024 -#define N_ITERATIONS 16 -int -main (int argc, char **argv) -{ - int array[TREE_SIZE]; - int seed; - int iteration; - - if (argc == 2) - seed = atoi (argv[1]); - else - seed = time (0) * 257 % 32768; - - fputs ("Testing avl...\n", stdout); - - for (iteration = 1; iteration <= N_ITERATIONS; iteration++) - { - avl_tree *tree; - int i; - - printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed); - fflush (stdout); - - srand (seed++); - - for (i = 0; i < TREE_SIZE; i++) - array[i] = i; - shuffle (array, TREE_SIZE); - - tree = avl_create (compare_ints, NULL); - for (i = 0; i < TREE_SIZE; i++) - avl_force_insert (tree, (void *) (array[i])); - verify_tree (tree); - - shuffle (array, TREE_SIZE); - for (i = 0; i < TREE_SIZE; i++) - { - avl_tree *copy; - - avl_delete (tree, (void *) (array[i])); - verify_tree (tree); - - copy = avl_copy (tree, NULL); - verify_tree (copy); - compare_trees (tree->root.link[0], copy->root.link[0]); - avl_destroy (copy, NULL); - - if (i % 128 == 0) - { - putchar ('.'); - fflush (stdout); - } - } - fputs (" good.\n", stdout); - - avl_destroy (tree, NULL); - } - - return 0; -} -#endif /* SELF_TEST */ - -/* - Local variables: - compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./avl-test avl.c" - End: -*/ - |