home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 347_01 / example1.c < prev    next >
C/C++ Source or Header  |  1991-10-22  |  6KB  |  189 lines

  1. /*
  2.  *  program Example1
  3.  *  purpose: test shell for threaded AVL-tree. mainly for profiling.
  4.  *
  5.  *  Usage:  EXAMPLE1 <filename>
  6.  *          file <filename> is a text file which contains a list a words,
  7.  *          one per line and left-adjusted. The list may contain duplicated
  8.  *          words.  Program reads the list, writes the words to the monitor
  9.  *          and inserts them into a threaded AVL tree.  Program pauses briefly,
  10.  *          then writes the list (with duplicates eliminated) to the monitor
  11.  *          in order.  Program pauses briefly again, and then items are
  12.  *          randomly deleted from the tree until it is empty. The tree is
  13.  *          then disposed and the program halts.
  14.  *
  15.  *  Copyright (c) 1991  Bert C. Hughes
  16.  *                      200 N. Saratoga
  17.  *                      St.Paul, MN 55104
  18.  *                      Compuserve 71211,577
  19.  */
  20.  
  21. #if defined NDEBUG
  22.      !*&^%$!!@@@()^H??||~:~:;:=+
  23.      File "Example1.c" MUST be compiled with NDEBUG undefined,
  24.      so that the "assert()" macro/function will be included.
  25. #endif
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <assert.h>
  31. #include "tavltree.h"
  32.  
  33. #if defined __TURBOC__
  34. #include <conio.h>
  35. #else
  36. #define cprintf printf
  37. #endif
  38.  
  39. void pause(void)
  40. {
  41.     int c;
  42.     cprintf("\r\nPress <ENTER> to continue...");
  43.     while (getchar() != '\n');
  44.     cprintf("\r\n");
  45. }
  46.  
  47. void *ident(void *x)    /* function to return identifier of data node */
  48. {                       /* is required by "tavl_init".  In this very  */
  49.     return x;           /* simple case, the identifier is simply what */
  50. }                       /* is being inserted into the tree - a string */
  51.  
  52. void *make_str(const void *s)
  53. {
  54.     int size = 1 + strlen((char *)s);
  55.     char *p = malloc(size);
  56.     return(memcpy(p,s,size));
  57. }
  58.  
  59.  
  60. main (int argc, char *argv[])
  61. {
  62.     TAVL_treeptr tree;
  63.     TAVL_nodeptr p;
  64.     unsigned int n,i,k;
  65.     char **name;
  66.     char s[128];
  67.  
  68.     int (*cmp)() = strcmp;  /* use C library function "strcmp" to compare */
  69.                             /* identifiers of nodes */
  70.     void *(*cpy)() = strcpy;/* pass to "tavl_init" as data copier "readitem"*/
  71.  
  72.     FILE *fp;
  73.  
  74. #if defined __TURBOC__
  75.     directvideo = 0;   /* change to 1 if there is "snow" on your monitor */
  76. #endif
  77.  
  78.     cprintf("FYI: sizeof(TAVL_NODE) = %d\r\n",sizeof(TAVL_NODE));
  79.     pause();
  80.  
  81.     /* open a file which contains a list of words, one per line */
  82.  
  83.     if (argc < 2)
  84.         strcpy(s,"WORDLIST");
  85.     else
  86.         strcpy(s,argv[1]);
  87.  
  88.     assert((fp = fopen(s,"r")) != NULL);
  89.  
  90.     /* initialize the tree */
  91.     assert((tree = tavl_init(cmp,ident,make_str,free,cpy,malloc,free)));
  92.  
  93.     cprintf("First, \"%s\" will be read and words found inserted into the tree.\r\n",s);
  94.     pause();
  95.  
  96.     /* build tree of words */
  97.     while (fscanf(fp,"%s",s) != EOF)
  98.         if (tavl_insert(tree,s,REPLACE) == NULL) {
  99.             cprintf("Out of memory!\r\n");
  100.             exit(0);
  101.         }
  102.  
  103.    /* check that all identifiers inserted can be found */
  104.  
  105.     cprintf("Tree is built. Next, word file will be re-read to verify that\r\nall words are in the tree and can be found.\r\n");
  106.     pause();
  107.  
  108.     fseek(fp,0,SEEK_SET);
  109.     cprintf("Testing 'Find'\r\n");
  110.  
  111.     while (fscanf(fp,"%s",s) != EOF) {
  112.         cprintf("%-10.8s",s);
  113.         assert(tavl_find(tree,s) != NULL);
  114.     }
  115.  
  116.     cprintf("\r\n\nFind OK.\r\n");
  117.     cprintf("Next, data items inserted into the tree will be listed in ascending order.\r\n");
  118.  
  119.     pause();
  120.  
  121.     fclose(fp);
  122.  
  123.     cprintf("In order:\r\n");
  124.     p = tavl_reset(tree);
  125.     n = 0;
  126.     while (p = tavl_succ(p)) {
  127.         n++;
  128.         cprintf("%-10.8s",p->dataptr);  /*dangerous to use dataptr directly*/
  129.     }
  130.     cprintf("\r\n\nNodes = %u\r\n",n);
  131.  
  132.     k = n;
  133.     p = tavl_reset(tree);
  134.  
  135.     if ((name = malloc(n * sizeof(char *))) == NULL) {
  136.         cprintf("\r\nOut of memory, can't do random deletions test.\r\n");
  137.         cprintf("Testing count in reverse direction...\r\n");
  138.         while (p = tavl_pred(p)) n--;
  139.         assert(n==0);
  140.         cprintf("Reverse direction tested & OK.\r\n");
  141.         exit(0);
  142.     }
  143.  
  144.     cprintf("\r\nNext: An array is filled for random deletions while passing through TAVLtree\r\nin reverse direction.  Words will not be written to output.\r\n");
  145.     pause();
  146.  
  147.     while (p = tavl_pred(p))
  148.         *(name + --k) = p->dataptr;
  149.                                       /* Direct use of a field of TAVL_NODE*/
  150.                                       /* All fields are READONLY! Only tavl-*/
  151.                                       /* library routines alter tree & */
  152.                                       /* node field values. */
  153.     assert(k==0);
  154.  
  155.     cprintf("\r\nReverse direction tested & OK.\r\n");
  156.     cprintf("\r\nDelete test:  words to delete will be randomly selected from the array just\r\nfilled, written to screen, and then deleted from the TAVLtree.\r\n");
  157.     pause();
  158.  
  159.     randomize();
  160.  
  161.     cprintf("\r\nDelete test:\r\n");
  162.  
  163.     while (n) {
  164.         i = random(n--);            /* select random identifier to delete */
  165.         cprintf("%-10.8s",*(name + i));
  166.         tavl_delete(tree,*(name + i));     /* delete it */
  167.         for (; i < n; i++)                 /* shrink the names list */
  168.             *(name + i) = *(name + i + 1);
  169.     }
  170.  
  171.     p = tavl_reset(tree);           /* make sure the tree is empty */
  172.     if (tavl_succ(p) != NULL) {
  173.         cprintf("Can't happen: tree still conatains nodes - successor.\r\n");
  174.         exit(0);
  175.     }
  176.  
  177.     p = tavl_reset(tree);           /* make sure the tree is empty */
  178.     if (tavl_pred(p) != NULL) {
  179.         cprintf("Can't happen: tree still conatains nodes - predecessor.\r\n");
  180.         exit(0);
  181.     }
  182.  
  183.     cprintf("\r\nDelete OK.\r\n");
  184.  
  185.     tavl_destroy(tree);
  186.  
  187.     cprintf("OK - tree destroyed - bye.");
  188. }
  189.