avl.c
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:24k
源码类别:

信息检索与抽取

开发平台:

Unix_Linux

  1. /* libavl - manipulates AVL trees.
  2.    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
  3.    This program is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU General Public License as
  5.    published by the Free Software Foundation; either version 2 of the
  6.    License, or (at your option) any later version.
  7.    This program is distributed in the hope that it will be useful, but
  8.    WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10.    General Public License for more details.
  11.    You should have received a copy of the GNU General Public License
  12.    along with this program; if not, write to the Free Software
  13.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  14.    02111-1307, USA.
  15.    The author may be contacted at <pfaffben@pilot.msu.edu> on the
  16.    Internet, or as Ben Pfaff, 12167 Airport Rd, DeWitt MI 48820, USA
  17.    through more mundane means. */
  18. /* This is file avl.c in libavl. */
  19. /* Modified by mgd@swarm.org 2000-09-10 to disable HAVE_CONFIG_H and PSPP code.
  20.    Force definition of HAVE_XMALLOC. */
  21. #if 0
  22. #if HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #if PSPP
  26. #include "common.h"
  27. #include "arena.h"
  28. #define HAVE_XMALLOC 1
  29. #endif
  30. #endif
  31. #define HAVE_XMALLOC
  32. #if SELF_TEST 
  33. #include <limits.h>
  34. #include <time.h>
  35. #endif
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <assert.h>
  39. #include "avl.h"
  40. #if !PSPP && !__GCC__
  41. #define inline
  42. #endif
  43. #if !PSPP
  44. #if __GNUC__ >= 2
  45. #define unused __attribute__ ((unused))
  46. #else
  47. #define unused
  48. #endif
  49. #endif
  50. #ifdef HAVE_XMALLOC
  51. void *xmalloc (size_t);
  52. void xfree (void *ptr);
  53. #else /* !HAVE_XMALLOC */
  54. /* Allocates SIZE bytes of space using malloc().  Aborts if out of
  55.    memory. */
  56. static void *
  57. xmalloc (size_t size)
  58. {
  59.   void *vp;
  60.   if (size == 0)
  61.     return NULL;
  62.   vp = malloc (size);
  63.   assert (vp != NULL);
  64.   if (vp == NULL)
  65.     {
  66.       fprintf (stderr, "virtual memory exhaustedn");
  67.       exit (EXIT_FAILURE);
  68.     }
  69.   return vp;
  70. }
  71. #endif /* !HAVE_XMALLOC */
  72. /* Creates an AVL tree in arena OWNER (which can be NULL).  The arena
  73.    is owned by the caller, not by the AVL tree.  CMP is a order
  74.    function for the data to be stored in the tree.  PARAM is arbitrary
  75.    data that becomes an argument to the comparison function. */
  76. avl_tree *
  77. avl_create (MAYBE_ARENA avl_comparison_func cmp, void *param)
  78. {
  79.   avl_tree *tree;
  80.   assert (cmp != NULL);
  81. #if PSPP
  82.   if (owner)
  83.     tree = arena_alloc (owner, sizeof (avl_tree));
  84.   else
  85. #endif
  86.     tree = xmalloc (sizeof (avl_tree));
  87. #if PSPP
  88.   tree->owner = owner;
  89. #endif
  90.   tree->root.link[0] = NULL;
  91.   tree->root.link[1] = NULL; 
  92.   tree->cmp = cmp;
  93.   tree->count = 0;
  94.   tree->param = param;
  95.   return tree;
  96. }
  97. /* Destroy tree TREE.  Function FREE_FUNC is called for every node in
  98.    the tree as it is destroyed.  
  99.    No effect if the tree has an arena owner and free_func is NULL.
  100.    The caller owns the arena and must destroy it itself.
  101.    Do not attempt to reuse the tree after it has been freed.  Create a
  102.    new one.  */
  103. void
  104. avl_destroy (avl_tree *tree, avl_node_func free_func)
  105. {
  106.   assert (tree != NULL);
  107.   
  108. #if PSPP
  109.   if (free_func || tree->owner == NULL)
  110. #endif
  111.     {
  112.       /* Uses Knuth's Algorithm 2.3.1T as modified in exercise 13
  113.  (postorder traversal). */
  114.       
  115.       /* T1. */
  116.       avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */
  117.       char ab[AVL_MAX_HEIGHT]; /* Stack A: bits. */
  118.       int ap = 0; /* Stack A: height. */
  119.       avl_node *p = tree->root.link[0];
  120.       for (;;)
  121. {
  122.   /* T2. */
  123.   while (p != NULL)
  124.     {
  125.       /* T3. */
  126.       ab[ap] = 0;
  127.       an[ap++] = p;
  128.       p = p->link[0];
  129.     }
  130.   /* T4. */
  131.   for (;;)
  132.     {
  133.       if (ap == 0)
  134. goto done;
  135.       p = an[--ap];
  136.       if (ab[ap] == 0)
  137. {
  138.   ab[ap++] = 1;
  139.   p = p->link[1];
  140.   break;
  141. }
  142.       
  143.       if (free_func)
  144. free_func (p->data, tree->param);
  145. #if PSPP
  146.       if (tree->owner == NULL)
  147. #endif
  148. xfree (p);
  149.     }
  150. }
  151.     }
  152.  done:
  153. #if PSPP
  154.   if (tree->owner == NULL)
  155. #endif
  156.     xfree (tree);
  157. }
  158. /* avl_destroy() with FREE_FUNC hardcoded as free(). */
  159. void
  160. avl_free (avl_tree *tree)
  161. {
  162.   avl_destroy (tree, (avl_node_func) xfree);
  163. }
  164. /* Return the number of nodes in TREE. */
  165. int
  166. avl_count (const avl_tree *tree)
  167. {
  168.   assert (tree != NULL);
  169.   return tree->count;
  170. }
  171. /* Allocates room for a new avl_node in arena OWNER, or using
  172.    xmalloc() if OWNER is NULL. */
  173. #if PSPP
  174. static inline avl_node *
  175. new_node (arena **owner)
  176. {
  177.   if (owner != NULL)
  178.     return arena_alloc (owner, sizeof (avl_node));
  179.   else
  180.     return xmalloc (sizeof (avl_node));
  181. }
  182. #else
  183. static inline avl_node *
  184. new_node (void)
  185. {
  186.   return xmalloc (sizeof (avl_node));
  187. }
  188. #define new_node(owner)
  189. new_node ()
  190. #endif
  191. /* Copy the contents of TREE to a new tree in arena OWNER.  If COPY is
  192.    non-NULL, then each data item is passed to function COPY, and the
  193.    return values are inserted into the new tree; otherwise, the items
  194.    are copied verbatim from the old tree to the new tree.  Returns the
  195.    new tree. */
  196. avl_tree *
  197. avl_copy (MAYBE_ARENA const avl_tree *tree, avl_copy_func copy)
  198. {
  199.   /* This is a combination of Knuth's Algorithm 2.3.1C (copying a
  200.      binary tree) and Algorithm 2.3.1T as modified by exercise 12
  201.      (preorder traversal). */
  202.   avl_tree *new_tree;
  203.   /* PT1. */
  204.   const avl_node *pa[AVL_MAX_HEIGHT]; /* Stack PA: nodes. */
  205.   const avl_node **pp = pa; /* Stack PA: stack pointer. */
  206.   const avl_node *p = &tree->root;
  207.   
  208.   /* QT1. */
  209.   avl_node *qa[AVL_MAX_HEIGHT]; /* Stack QA: nodes. */
  210.   avl_node **qp = qa; /* Stack QA: stack pointer. */
  211.   avl_node *q;
  212.   
  213.   assert (tree != NULL);
  214. #if PSPP
  215.   new_tree = avl_create (owner, tree->cmp, tree->param);
  216. #else
  217.   new_tree = avl_create (tree->cmp, tree->param);
  218. #endif
  219.   new_tree->count = tree->count;
  220.   q = &new_tree->root;
  221.   for (;;)
  222.     {
  223.       /* C4. */
  224.       if (p->link[0] != NULL)
  225. {
  226.   avl_node *r = new_node (owner);
  227.   r->link[0] = r->link[1] = NULL;
  228.   q->link[0] = r;
  229. }
  230.       /* C5: Find preorder successors of P and Q.  */
  231.       goto start;
  232.       for (;;)
  233. {
  234.   /* PT2. */
  235.   while (p != NULL)
  236.     {
  237.       goto escape;
  238.     start:
  239.       /* PT3. */
  240.       *pp++ = p;
  241.       *qp++ = q;
  242.       p = p->link[0];
  243.       q = q->link[0];
  244.     }
  245.       
  246.   /* PT4. */
  247.   if (pp == pa)
  248.     {
  249.       assert (qp == qa);
  250.       return new_tree;
  251.     }
  252.       
  253.   p = *--pp;
  254.   q = *--qp;
  255.   /* PT5. */
  256.   p = p->link[1];
  257.   q = q->link[1];
  258. }
  259.     escape:
  260.       /* C2. */
  261.       if (p->link[1])
  262. {
  263.   avl_node *r = new_node (owner);
  264.   r->link[0] = r->link[1] = NULL;
  265.   q->link[1] = r;
  266. }
  267.       /* C3. */
  268.       q->bal = p->bal;
  269.       if (copy == NULL)
  270. q->data = p->data;
  271.       else
  272. q->data = copy (p->data, tree->param);
  273.     }
  274. }
  275. /* Walk tree TREE in inorder, calling WALK_FUNC at each node.  Passes
  276.    PARAM to WALK_FUNC.  */
  277. void
  278. avl_walk (const avl_tree *tree, avl_node_func walk_func, void *param)
  279. {
  280.   /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */
  281.   assert (tree && walk_func);
  282.   
  283.   {
  284.     /* T1. */
  285.     const avl_node *an[AVL_MAX_HEIGHT]; /* Stack A: nodes. */
  286.     const avl_node **ap = an; /* Stack A: stack pointer. */
  287.     const avl_node *p = tree->root.link[0];
  288.     for (;;)
  289.       {
  290. /* T2. */
  291. while (p != NULL)
  292.   {
  293.     /* T3. */
  294.     *ap++ = p;
  295.     p = p->link[0];
  296.   }
  297.       
  298. /* T4. */
  299. if (ap == an)
  300.   return;
  301. p = *--ap;
  302. /* T5. */
  303. walk_func (p->data, param);
  304. p = p->link[1];
  305.       }
  306.   }
  307. }
  308. /* Each call to this function for a given TREE and TRAV return the
  309.    next item in the tree in inorder.  Initialize the first element of
  310.    TRAV (init) to 0 before calling the first time.  Returns NULL when
  311.    out of elements.  */
  312. void *
  313. avl_traverse (const avl_tree *tree, avl_traverser *trav)
  314. {
  315.   assert (tree && trav);
  316.   /* Uses Knuth's algorithm 2.3.1T (inorder traversal). */
  317.   if (trav->init == 0)
  318.     {
  319.       /* T1. */
  320.       trav->init = 1;
  321.       trav->nstack = 0;
  322.       trav->p = tree->root.link[0];
  323.     }
  324.   else
  325.     /* T5. */
  326.     trav->p = trav->p->link[1];
  327.   for (;;)
  328.     {
  329.       /* T2. */
  330.       while (trav->p != NULL)
  331. {
  332.   /* T3. */
  333.   trav->stack[trav->nstack++] = trav->p;
  334.   trav->p = trav->p->link[0];
  335. }
  336.       
  337.       /* T4. */
  338.       if (trav->nstack == 0)
  339. {
  340.   trav->init = 0;
  341.   return NULL;
  342. }
  343.       trav->p = trav->stack[--trav->nstack];
  344.       /* T5. */
  345.       return trav->p->data;
  346.     }
  347. }
  348. /* Search TREE for an item matching ITEM.  If found, returns a pointer
  349.    to the address of the item.  If none is found, ITEM is inserted
  350.    into the tree, and a pointer to the address of ITEM is returned.
  351.    In either case, the pointer returned can be changed by the caller,
  352.    or the returned data item can be directly edited, but the key data
  353.    in the item must not be changed. */
  354. void **
  355. avl_probe (avl_tree *tree, void *item)
  356. {
  357.   /* Uses Knuth's Algorithm 6.2.3A (balanced tree search and
  358.      insertion), but caches results of comparisons.  In empirical
  359.      tests this eliminates about 25% of the comparisons seen under
  360.      random insertions.  */
  361.   /* A1. */
  362.   avl_node *t;
  363.   avl_node *s, *p, *q, *r;
  364.   
  365.   assert (tree != NULL);
  366.   t = &tree->root;
  367.   s = p = t->link[0];
  368.   if (s == NULL)
  369.     {
  370.       tree->count++;
  371.       assert (tree->count == 1);
  372.       q = t->link[0] = new_node (tree->owner);
  373.       q->data = item;
  374.       q->link[0] = q->link[1] = NULL;
  375.       q->bal = 0;
  376.       return &q->data;
  377.     }
  378.   for (;;)
  379.     {
  380.       /* A2. */
  381.       int diff = tree->cmp (item, p->data, tree->param);
  382.       /* A3. */
  383.       if (diff < 0)
  384. {
  385.   p->cache = 0;
  386.   q = p->link[0];
  387.   if (q == NULL)
  388.     {
  389.       p->link[0] = q = new_node (tree->owner);
  390.       break;
  391.     }
  392. }
  393.       /* A4. */
  394.       else if (diff > 0)
  395. {
  396.   p->cache = 1;
  397.   q = p->link[1];
  398.   if (q == NULL)
  399.     {
  400.       p->link[1] = q = new_node (tree->owner);
  401.       break;
  402.     }
  403. }
  404.       else
  405. /* A2. */
  406. return &p->data;
  407.       /* A3, A4. */
  408.       if (q->bal != 0)
  409. t = p, s = q;
  410.       p = q;
  411.     }
  412.   
  413.   /* A5. */
  414.   tree->count++;
  415.   q->data = item;
  416.   q->link[0] = q->link[1] = NULL;
  417.   q->bal = 0;
  418.   /* A6. */
  419.   r = p = s->link[(int) s->cache];
  420.   while (p != q)
  421.     {
  422.       p->bal = p->cache * 2 - 1;
  423.       p = p->link[(int) p->cache];
  424.     }
  425.   /* A7. */
  426.   if (s->cache == 0)
  427.     {
  428.       /* a = -1. */
  429.       if (s->bal == 0)
  430. {
  431.   s->bal = -1;
  432.   return &q->data;
  433. }
  434.       else if (s->bal == +1)
  435. {
  436.   s->bal = 0;
  437.   return &q->data;
  438. }
  439.       
  440.       assert (s->bal == -1);
  441.       if (r->bal == -1)
  442. {
  443.   /* A8. */
  444.   p = r;
  445.   s->link[0] = r->link[1];
  446.   r->link[1] = s;
  447.   s->bal = r->bal = 0;
  448. }
  449.       else
  450. {
  451.   /* A9. */
  452.   assert (r->bal == +1);
  453.   p = r->link[1];
  454.   r->link[1] = p->link[0];
  455.   p->link[0] = r;
  456.   s->link[0] = p->link[1];
  457.   p->link[1] = s;
  458.   if (p->bal == -1)
  459.     s->bal = 1, r->bal = 0;
  460.   else if (p->bal == 0)
  461.     s->bal = r->bal = 0;
  462.   else 
  463.     {
  464.       assert (p->bal == +1);
  465.       s->bal = 0, r->bal = -1;
  466.     }
  467.   p->bal = 0;
  468. }
  469.     }
  470.   else
  471.     {
  472.       /* a == +1. */
  473.       if (s->bal == 0)
  474. {
  475.   s->bal = 1;
  476.   return &q->data;
  477. }
  478.       else if (s->bal == -1)
  479. {
  480.   s->bal = 0;
  481.   return &q->data;
  482. }
  483.       assert (s->bal == +1);
  484.       if (r->bal == +1)
  485. {
  486.   /* A8. */
  487.   p = r;
  488.   s->link[1] = r->link[0];
  489.   r->link[0] = s;
  490.   s->bal = r->bal = 0;
  491. }
  492.       else
  493. {
  494.   /* A9. */
  495.   assert (r->bal == -1);
  496.   p = r->link[0];
  497.   r->link[0] = p->link[1];
  498.   p->link[1] = r;
  499.   s->link[1] = p->link[0];
  500.   p->link[0] = s;
  501.   if (p->bal == +1)
  502.     s->bal = -1, r->bal = 0;
  503.   else if (p->bal == 0)
  504.     s->bal = r->bal = 0;
  505.   else 
  506.     {
  507.       assert (p->bal == -1);
  508.       s->bal = 0, r->bal = 1;
  509.     }
  510.   p->bal = 0;
  511. }
  512.     }
  513.   /* A10. */
  514.   if (t != &tree->root && s == t->link[1])
  515.     t->link[1] = p;
  516.   else
  517.     t->link[0] = p;
  518.   return &q->data;
  519. }
  520.   
  521. /* Search TREE for an item matching ITEM, and return it if found. */
  522. void *
  523. avl_find (const avl_tree *tree, const void *item)
  524. {
  525.   const avl_node *p;
  526.   assert (tree != NULL);
  527.   for (p = tree->root.link[0]; p; )
  528.     {
  529.       int diff = tree->cmp (item, p->data, tree->param);
  530.       if (diff < 0)
  531. p = p->link[0];
  532.       else if (diff > 0)
  533. p = p->link[1];
  534.       else
  535. return p->data;
  536.     }
  537.   return NULL;
  538. }
  539. /* Search TREE for an item close to the value of ITEM, and return it.
  540.    This function will return a null pointer only if TREE is empty. */
  541. void *
  542. avl_find_close (const avl_tree *tree, const void *item)
  543. {
  544.   const avl_node *p;
  545.   assert (tree != NULL);
  546.   p = tree->root.link[0];
  547.   if (p == NULL)
  548.     return NULL;
  549.   
  550.   for (;;)
  551.     {
  552.       int diff = tree->cmp (item, p->data, tree->param);
  553.       int t;
  554.       if (diff < 0)
  555. t = 0;
  556.       else if (diff > 0)
  557. t = 1;
  558.       else
  559. return p->data;
  560.       if (p->link[t])
  561. p = p->link[t];
  562.       else
  563. return p->data;
  564.     }
  565. }
  566. /* Searches AVL tree TREE for an item matching ITEM.  If found, the
  567.    item is removed from the tree and the actual item found is returned
  568.    to the caller.  If no item matching ITEM exists in the tree,
  569.    returns NULL. */
  570. void *
  571. avl_delete (avl_tree *tree, const void *item)
  572. {
  573.   /* Uses my Algorithm D, which can be found at
  574.      http://www.msu.edu/user/pfaffben/avl.  Algorithm D is based on
  575.      Knuth's Algorithm 6.2.2D (Tree deletion) and 6.2.3A (Balanced
  576.      tree search and insertion), as well as the notes on pages 465-466
  577.      of Vol. 3. */
  578.   /* D1. */
  579.   avl_node *pa[AVL_MAX_HEIGHT]; /* Stack P: Nodes. */
  580.   char a[AVL_MAX_HEIGHT]; /* Stack P: Bits. */
  581.   int k = 1; /* Stack P: Pointer. */
  582.   
  583.   avl_node **q;
  584.   avl_node *p;
  585.   assert (tree != NULL);
  586.   a[0] = 0;
  587.   pa[0] = &tree->root;
  588.   p = tree->root.link[0];
  589.   for (;;)
  590.     {
  591.       /* D2. */
  592.       int diff;
  593.       if (p == NULL)
  594. return NULL;
  595.       diff = tree->cmp (item, p->data, tree->param);
  596.       if (diff == 0)
  597. break;
  598.       /* D3, D4. */
  599.       pa[k] = p;
  600.       if (diff < 0)
  601. {
  602.   p = p->link[0];
  603.   a[k] = 0;
  604. }
  605.       else if (diff > 0)
  606. {
  607.   p = p->link[1];
  608.   a[k] = 1;
  609. }
  610.       k++;
  611.     }
  612.   tree->count--;
  613.   
  614.   item = p->data;
  615.   /* D5. */
  616.   q = &pa[k - 1]->link[(int) a[k - 1]];
  617.   if (p->link[1] == NULL)
  618.     {
  619.       *q = p->link[0];
  620.       if (*q)
  621. (*q)->bal = 0;
  622.     }
  623.   else
  624.     {
  625.       /* D6. */
  626.       avl_node *r = p->link[1];
  627.       if (r->link[0] == NULL)
  628. {
  629.   r->link[0] = p->link[0];
  630.   *q = r;
  631.   r->bal = p->bal;
  632.   a[k] = 1;
  633.   pa[k++] = r;
  634. }
  635.       else
  636. {
  637.   /* D7. */
  638.   avl_node *s = r->link[0];
  639.   int l = k++;
  640.   a[k] = 0;
  641.   pa[k++] = r;
  642.     
  643.   /* D8. */
  644.   while (s->link[0] != NULL)
  645.     {
  646.       r = s;
  647.       s = r->link[0];
  648.       a[k] = 0;
  649.       pa[k++] = r;
  650.     }
  651.   /* D9. */
  652.   a[l] = 1;
  653.   pa[l] = s;
  654.   s->link[0] = p->link[0];
  655.   r->link[0] = s->link[1];
  656.   s->link[1] = p->link[1];
  657.   s->bal = p->bal;
  658.   *q = s;
  659. }
  660.     }
  661. #if PSPP
  662.   if (tree->owner == NULL)
  663. #endif
  664.     xfree (p);
  665.   assert (k > 0);
  666.   /* D10. */
  667.   while (--k)
  668.     {
  669.       avl_node *s = pa[k], *r;
  670.       if (a[k] == 0)
  671. {
  672.   /* D10. */
  673.   if (s->bal == -1)
  674.     {
  675.       s->bal = 0;
  676.       continue;
  677.     }
  678.   else if (s->bal == 0)
  679.     {
  680.       s->bal = 1;
  681.       break;
  682.     }
  683.   assert (s->bal == +1);
  684.   r = s->link[1];
  685.   assert (r != NULL);
  686.   if (r->bal == 0)
  687.     {
  688.       /* D11. */
  689.       s->link[1] = r->link[0];
  690.       r->link[0] = s;
  691.       r->bal = -1;
  692.       pa[k - 1]->link[(int) a[k - 1]] = r;
  693.       break;
  694.     }
  695.   else if (r->bal == +1)
  696.     {
  697.       /* D12. */
  698.       s->link[1] = r->link[0];
  699.       r->link[0] = s;
  700.       s->bal = r->bal = 0;
  701.       pa[k - 1]->link[(int) a[k - 1]] = r;
  702.     }
  703.   else 
  704.     {
  705.       /* D13. */
  706.       assert (r->bal == -1);
  707.       p = r->link[0];
  708.       r->link[0] = p->link[1];
  709.       p->link[1] = r;
  710.       s->link[1] = p->link[0];
  711.       p->link[0] = s;
  712.       if (p->bal == +1)
  713. s->bal = -1, r->bal = 0;
  714.       else if (p->bal == 0)
  715. s->bal = r->bal = 0;
  716.       else
  717. {
  718.   assert (p->bal == -1);
  719.   s->bal = 0, r->bal = +1;
  720. }
  721.       p->bal = 0;
  722.       pa[k - 1]->link[(int) a[k - 1]] = p;
  723.     }
  724. }
  725.       else
  726. {
  727.   assert (a[k] == 1);
  728.   /* D10. */
  729.   if (s->bal == +1)
  730.     {
  731.       s->bal = 0;
  732.       continue;
  733.     }
  734.   else if (s->bal == 0)
  735.     {
  736.       s->bal = -1;
  737.       break;
  738.     }
  739.   assert (s->bal == -1);
  740.   r = s->link[0];
  741.   if (r == NULL || r->bal == 0)
  742.     {
  743.       /* D11. */
  744.       s->link[0] = r->link[1];
  745.       r->link[1] = s;
  746.       r->bal = 1;
  747.       pa[k - 1]->link[(int) a[k - 1]] = r;
  748.       break;
  749.     }
  750.   else if (r->bal == -1)
  751.     {
  752.       /* D12. */
  753.       s->link[0] = r->link[1];
  754.       r->link[1] = s;
  755.       s->bal = r->bal = 0;
  756.       pa[k - 1]->link[(int) a[k - 1]] = r;
  757.     }
  758.   else if (r->bal == +1)
  759.     {
  760.       /* D13. */
  761.       p = r->link[1];
  762.       r->link[1] = p->link[0];
  763.       p->link[0] = r;
  764.       s->link[0] = p->link[1];
  765.       p->link[1] = s;
  766.       if (p->bal == -1)
  767. s->bal = 1, r->bal = 0;
  768.       else if (p->bal == 0)
  769. s->bal = r->bal = 0;
  770.       else
  771. {
  772.   assert (p->bal == 1);
  773.   s->bal = 0, r->bal = -1;
  774. }
  775.       p->bal = 0;
  776.       pa[k - 1]->link[(int) a[k - 1]] = p;
  777.     }
  778. }
  779.     }
  780.       
  781.   return (void *) item;
  782. }
  783. /* Inserts ITEM into TREE.  Returns NULL if the item was inserted,
  784.    otherwise a pointer to the duplicate item. */
  785. void *
  786. avl_insert (avl_tree *tree, void *item)
  787. {
  788.   void **p;
  789.   
  790.   assert (tree != NULL);
  791.   
  792.   p = avl_probe (tree, item);
  793.   return (*p == item) ? NULL : *p;
  794. }
  795. /* If ITEM does not exist in TREE, inserts it and returns NULL.  If a
  796.    matching item does exist, it is replaced by ITEM and the item
  797.    replaced is returned.  The caller is responsible for freeing the
  798.    item returned. */
  799. void *
  800. avl_replace (avl_tree *tree, void *item)
  801. {
  802.   void **p;
  803.   assert (tree != NULL);
  804.   
  805.   p = avl_probe (tree, item);
  806.   if (*p == item)
  807.     return NULL;
  808.   else
  809.     {
  810.       void *r = *p;
  811.       *p = item;
  812.       return r;
  813.     }
  814. }
  815. /* Delete ITEM from TREE when you know that ITEM must be in TREE.  For
  816.    debugging purposes. */
  817. void *
  818. (avl_force_delete) (avl_tree *tree, void *item)
  819. {
  820.   void *found = avl_delete (tree, item);
  821.   assert (found != NULL);
  822.   return found;
  823. }
  824. #if SELF_TEST
  825. /* Used to flag delayed aborting. */
  826. int done = 0;
  827. /* Print the structure of node NODE of an avl tree, which is LEVEL
  828.    levels from the top of the tree.  Uses different delimiters to
  829.    visually distinguish levels. */
  830. void
  831. print_structure (avl_node *node, int level)
  832. {
  833.   char lc[] = "([{`/";
  834.   char rc[] = ")]}'\";
  835.   assert (level <= 10);
  836.   
  837.   if (node == NULL)
  838.     {
  839.       printf (" nil");
  840.       return;
  841.     }
  842.   printf (" %c%d", lc[level % 5], (int) node->data);
  843.   if (node->link[0] || node->link[1])
  844.     print_structure (node->link[0], level + 1);
  845.   if (node->link[1])
  846.     print_structure (node->link[1], level + 1);
  847.   printf ("%c", rc[level % 5]);
  848. }
  849. /* Compare two integers A and B and return a strcmp()-type result. */
  850. int
  851. compare_ints (const void *a, const void *b, void *param unused)
  852. {
  853.   return ((int) a) - ((int) b);
  854. }
  855. /* Print the value of integer A. */
  856. void
  857. print_int (void *a, void *param unused)
  858. {
  859.   printf (" %d", (int) a);
  860. }
  861. /* Linearly print contents of TREE. */
  862. void
  863. print_contents (avl_tree *tree)
  864. {
  865.   avl_walk (tree, print_int, NULL);
  866.   printf ("n");
  867. }
  868. /* Examine NODE in a avl tree.  *COUNT is increased by the number of
  869.    nodes in the tree, including the current one.  If the node is the
  870.    root of the tree, PARENT should be INT_MIN, otherwise it should be
  871.    the parent node value.  DIR is the direction that the current node
  872.    is linked from the parent: -1 for left child, +1 for right child;
  873.    it is not used if PARENT is INT_MIN.  Returns the height of the
  874.    tree rooted at NODE. */
  875. int
  876. recurse_tree (avl_node *node, int *count, int parent, int dir)
  877. {
  878.   if (node) 
  879.     {
  880.       int d = (int) node->data;
  881.       int nl = node->link[0] ? recurse_tree (node->link[0], count, d, -1) : 0;
  882.       int nr = node->link[1] ? recurse_tree (node->link[1], count, d, 1) : 0;
  883.       (*count)++;
  884.       if (nr - nl != node->bal)
  885. {
  886.   printf (" Node %d is unbalanced: right height=%d, left height=%d, "
  887. "difference=%d, but balance factor=%d.n",
  888.   d, nr, nl, nr - nl, node->bal);
  889.   done = 1;
  890. }
  891.       
  892.       if (parent != INT_MIN)
  893. {
  894.   assert (dir == -1 || dir == +1);
  895.   if (dir == -1 && d > parent)
  896.     {
  897.       printf (" Node %d is smaller than its left child %d.n",
  898.       parent, d);
  899.       done = 1;
  900.     }
  901.   else if (dir == +1 && d < parent)
  902.     {
  903.       printf (" Node %d is larger than its right child %d.n",
  904.       parent, d);
  905.       done = 1;
  906.     }
  907. }
  908.       assert (node->bal >= -1 && node->bal <= 1);
  909.       return 1 + (nl > nr ? nl : nr);
  910.     }
  911.   else return 0;
  912. }
  913. /* Check that everything about TREE is kosher. */
  914. void
  915. verify_tree (avl_tree *tree)
  916. {
  917.   int count = 0;
  918.   recurse_tree (tree->root.link[0], &count, INT_MIN, 0);
  919.   if (count != tree->count)
  920.     {
  921.       printf (" Tree has %d nodes, but tree count is %d.n",
  922.       count, tree->count);
  923.       done = 1;
  924.     }
  925.   if (done)
  926.     abort ();
  927. }
  928. /* Arrange the N elements of ARRAY in random order. */
  929. void
  930. shuffle (int *array, int n)
  931. {
  932.   int i;
  933.   
  934.   for (i = 0; i < n; i++)
  935.     {
  936.       int j = i + rand () % (n - i);
  937.       int t = array[j];
  938.       array[j] = array[i];
  939.       array[i] = t;
  940.     }
  941. }
  942. /* Compares avl trees rooted at A and B, making sure that they are
  943.    identical. */
  944. void
  945. compare_trees (avl_node *a, avl_node *b)
  946. {
  947.   if (a == NULL || b == NULL)
  948.     {
  949.       assert (a == NULL && b == NULL);
  950.       return;
  951.     }
  952.   if (a->data != b->data || a->bal != b->bal
  953.       || ((a->link[0] != NULL) ^ (b->link[0] != NULL))
  954.       || ((a->link[1] != NULL) ^ (b->link[1] != NULL)))
  955.     {
  956.       printf (" Copied nodes differ: %d b=%d a->bal=%d b->bal=%d a:",
  957.       (int) a->data, (int) b->data, a->bal, b->bal);
  958.       if (a->link[0])
  959. printf ("l");
  960.       if (a->link[1])
  961. printf ("r");
  962.       printf (" b:");
  963.       if (b->link[0])
  964. printf ("l");
  965.       if (b->link[1])
  966. printf ("r");
  967.       printf ("n");
  968.       abort ();
  969.     }
  970.   if (a->link[0] != NULL)
  971.     compare_trees (a->link[0], b->link[0]);
  972.   if (a->link[1] != NULL)
  973.     compare_trees (a->link[1], b->link[1]);
  974. }
  975. /* Simple stress test procedure for the AVL tree routines.  Does the
  976.    following:
  977.    * Generate a random number seed.  By default this is generated from
  978.    the current time.  You can also pass a seed value on the command
  979.    line if you want to test the same case.  The seed value is
  980.    displayed.
  981.    * Create a tree and insert the integers from 0 up to TREE_SIZE - 1
  982.    into it, in random order.  Verify the tree structure after each
  983.    insertion.
  984.    
  985.    * Remove each integer from the tree, in a different random order.
  986.    After each deletion, verify the tree structure; also, make a copy
  987.    of the tree into a new tree, verify the copy and compare it to the
  988.    original, then destroy the copy.
  989.    * Destroy the tree, increment the random seed value, and start over.
  990.    If you make any modifications to the avl tree routines, then you
  991.    might want to insert some calls to print_structure() at strategic
  992.    places in order to be able to see what's really going on.  Also,
  993.    memory debuggers like Checker or Purify are very handy. */
  994. #define TREE_SIZE 1024
  995. #define N_ITERATIONS 16
  996. int
  997. main (int argc, char **argv)
  998. {
  999.   int array[TREE_SIZE];
  1000.   int seed;
  1001.   int iteration;
  1002.   
  1003.   if (argc == 2)
  1004.     seed = atoi (argv[1]);
  1005.   else
  1006.     seed = time (0) * 257 % 32768;
  1007.   fputs ("Testing avl...n", stdout);
  1008.   
  1009.   for (iteration = 1; iteration <= N_ITERATIONS; iteration++)
  1010.     {
  1011.       avl_tree *tree;
  1012.       int i;
  1013.       
  1014.       printf ("Iteration %4d/%4d: seed=%5d", iteration, N_ITERATIONS, seed);
  1015.       fflush (stdout);
  1016.       
  1017.       srand (seed++);
  1018.       for (i = 0; i < TREE_SIZE; i++)
  1019. array[i] = i;
  1020.       shuffle (array, TREE_SIZE);
  1021.       
  1022.       tree = avl_create (compare_ints, NULL);
  1023.       for (i = 0; i < TREE_SIZE; i++)
  1024. avl_force_insert (tree, (void *) (array[i]));
  1025.       verify_tree (tree);
  1026.       shuffle (array, TREE_SIZE);
  1027.       for (i = 0; i < TREE_SIZE; i++)
  1028. {
  1029.   avl_tree *copy;
  1030.   avl_delete (tree, (void *) (array[i]));
  1031.   verify_tree (tree);
  1032.   copy = avl_copy (tree, NULL);
  1033.   verify_tree (copy);
  1034.   compare_trees (tree->root.link[0], copy->root.link[0]);
  1035.   avl_destroy (copy, NULL);
  1036.   if (i % 128 == 0)
  1037.     {
  1038.       putchar ('.');
  1039.       fflush (stdout);
  1040.     }
  1041. }
  1042.       fputs (" good.n", stdout);
  1043.       avl_destroy (tree, NULL);
  1044.     }
  1045.   
  1046.   return 0;
  1047. }
  1048. #endif /* SELF_TEST */
  1049. /*
  1050.   Local variables:
  1051.   compile-command: "gcc -DSELF_TEST=1 -W -Wall -I. -o ./avl-test avl.c"
  1052.   End:
  1053. */