home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_01 / 1001075a < prev    next >
Text File  |  1991-11-22  |  6KB  |  219 lines

  1. /*
  2.  *      Traversal of multiple binary trees
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8.  
  9. #define BIGINT  (~(1 << ((8*sizeof(int))-1)))   /* maximum integer */
  10. #define NNODES  25      /* the number of nodes per tree */
  11. #define NTREES  10      /* the number of binary trees to traverse */
  12.  
  13. /* binary tree node definition */
  14. typedef struct  node    {
  15.         struct  node    *left;          /* left sub-tree */
  16.         struct  node    *right;         /* right sub-tree */
  17.         int             key;            /* current node value */
  18. }       NODE;
  19.  
  20. /***********************************************************************
  21.  * the following section is the single threaded example
  22.  ***********************************************************************/
  23. #ifdef  SINGLE_THREAD
  24.  
  25. /* stack frame definition */
  26. typedef struct frame    {
  27.         struct node     *data;          /* the node being stacked */
  28.         struct frame    *next;          /* the next stack entry */
  29. }       FRAME;
  30.  
  31. /* push a tree node onto the stack */
  32. void Push(FRAME **stackp, NODE *treep) {
  33. FRAME *temp;
  34.  
  35.         assert(treep != NULL);
  36.         temp = malloc(sizeof(FRAME));
  37.         assert(temp != NULL);
  38.         temp->data = treep;
  39.         temp->next = *stackp;
  40.         (*stackp) = temp;
  41. }
  42.  
  43. /* get the top data item from the stack (without popping) */
  44. int Top(FRAME *stackp) {
  45. NODE    *temp;
  46.  
  47.         assert(stackp != NULL);
  48.         temp = stackp->data;
  49.         return(temp->key);
  50. }
  51.  
  52. /* print the lowest value of all N trees */
  53. void DisplayLowest(FRAME *stackp[], int *lowest) {
  54. int current;
  55. int topvalue;
  56. int temp=BIGINT;
  57. int i;
  58.  
  59.         /* for each tree in the list... */
  60.         for (i=0; i < NTREES; i++) {
  61.                 /* if the tree has not been completely traversed, */
  62.                 if (stackp[i] != NULL) {
  63.                         /* get the current key of this tree */
  64.                         topvalue = Top(stackp[i]);
  65.                         /* compare the current key with the other trees */
  66.                         if (topvalue < temp) {
  67.                                 /* save the current tree number and its key */
  68.                                 current = i;
  69.                                 temp = topvalue;
  70.                         }
  71.                 }
  72.         }
  73.         printf("key = %d\n", temp);
  74.         *lowest = current;
  75. }
  76.  
  77. /* removes and returns the top entry from the stack */
  78. NODE *Pop(FRAME **stackp) {
  79. FRAME *temp;
  80. NODE *data;
  81.  
  82.         temp = *stackp;
  83.         *stackp = (*stackp)->next;
  84.         data = temp->data;
  85.         free(temp);
  86.         return(data);
  87. }
  88.  
  89. /* traverse the right sub-tree */
  90. void TraverseRightSub(FRAME **stackp) {
  91. NODE *temp;
  92. FRAME *sframe;
  93.  
  94.         /* find the right sub-tree of the current node */
  95.         temp = Pop(stackp);
  96.         temp = temp->right;
  97.  
  98.         /* traverse the sub tree as far left as possible */
  99.         while (temp != NULL) {
  100.                 Push(stackp, temp);
  101.                 temp = temp->left;
  102.         }
  103. }
  104.  
  105. /* determine if there are unvisited nodes */
  106. int StacksExist(FRAME *stackp[]) {
  107. int i;
  108.  
  109.         for (i = 0; i < NTREES; i++){
  110.                 if (stackp[i] != NULL)
  111.                         return(1);
  112.         }
  113.         return(0);
  114. }
  115.  
  116. void MergeTrees(NODE *treep[]) {
  117. FRAME *stackp[NTREES];
  118. int i;
  119.  
  120.         /* preload all stacks */
  121.         for (i = 0; i < NTREES; i++) {
  122.                 stackp[i] = NULL;
  123.                 while (treep[i] != NULL) {
  124.                         Push(&stackp[i], treep[i]);
  125.                         treep[i] = treep[i]->left;
  126.                 }
  127.         }
  128.         do {
  129.                 DisplayLowest(stackp, &i);
  130.                 TraverseRightSub(&stackp[i]);
  131.         } while(StacksExist(stackp));
  132. }
  133.  
  134. /***********************************************************************
  135.  * the following section is the multi threaded example
  136.  ***********************************************************************/
  137. #else
  138.  
  139. #include <multi_c.h>
  140.  
  141. /* print the contents of a node (wait until it is the lowest key) */
  142. void    PrintNode(NODE *tree) {
  143. static  int     CurrentKey = BIGINT;
  144.  
  145.         /* wait until this node contains the lowest key value */
  146.         do {
  147.                 if (CurrentKey > tree->key)
  148.                         CurrentKey = tree->key;
  149.                 MtCYield();
  150.         } while (CurrentKey != tree->key);
  151.         /* reinitialize the current key */
  152.         CurrentKey = BIGINT;
  153.         printf("key = %d\n", tree->key);
  154. }
  155.  
  156. /* recursively visit the nodes in a tree */
  157. void    PrintTree(NODE *tree) {
  158.  
  159.         if (tree != NULL) {
  160.                 PrintTree(tree->left);
  161.                 PrintNode(tree);
  162.                 PrintTree(tree->right);
  163.         }
  164. }
  165.  
  166. /* traverse multiple binary trees */
  167. void    MergeTrees(NODE **trees) {
  168. int     i;
  169.  
  170.         /* create a thread for each tree... */
  171.         for (i = 0; i < NTREES; i++) {
  172.                 MtCCoroutine(PrintTree(&trees[i]));
  173.         }
  174. }
  175.  
  176. #endif
  177.  
  178. /* recursively add a node to the tree */
  179. void    AddKey(NODE **treep, int key) {
  180.  
  181.         if ((*treep) == NULL) {
  182.                 (*treep) = malloc(sizeof(NODE));
  183.                 assert(*treep != NULL);
  184.                 (*treep)->left = NULL;
  185.                 (*treep)->right = NULL;
  186.                 (*treep)->key = key;
  187.         } else {
  188.                 if (key < (*treep)->key) {
  189.                         AddKey(&((*treep)->left), key);
  190.                 } else {
  191.                         AddKey(&((*treep)->right), key);
  192.                 }
  193.         }
  194. }
  195.  
  196. /* build a tree of NNODES random keys */
  197. void    BuildTree(NODE **treep) {
  198. int     i;
  199.  
  200.         for (i = 0; i < NNODES; i++) {
  201.                 AddKey(treep, rand());
  202.         }
  203. }
  204.  
  205.  
  206. void    main() {
  207. NODE    *trees[NTREES];
  208. int     i;
  209.  
  210.         /* randomly build the trees */
  211.         for (i = 0; i < NTREES; i++) {
  212.                 trees[i] = NULL;
  213.                 BuildTree(&trees[i]);
  214.         }
  215.         /* traverse the trees as a single tree */
  216.         MergeTrees(trees);
  217. }
  218.  
  219.