Advertisement
Guest User

ASCII Binary Tree

a guest
Sep 24th, 2013
4,472
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.09 KB | None | 0 0
  1. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2. !!!Code originally from /http://www.openasthra.com/c-tidbits/printing-binary-trees-in-ascii/
  3. !!! Just saved it, cause the website is down.
  4. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5. Printing Binary Trees in Ascii
  6.  
  7. Here we are not going to discuss what binary trees are (please refer this, if you are looking for binary search trees), or their operations but printing them in ascii.
  8.  
  9. The below routine prints tree in ascii for a given Tree representation which contains list of nodes, and node structure is this
  10.  
  11.     struct Tree
  12.     {
  13.       Tree * left, * right;
  14.       int element;
  15.     };
  16.  
  17. This pic illustrates what the below routine does on canvas..
  18. ascii tree
  19.  
  20. Here is the printing routine..
  21.  
  22.     b5855d39a6b8a2735ddcaa04a404c125001
  23.  
  24. Auxiliary routines..
  25.  
  26.     //This function prints the given level of the given tree, assuming
  27.     //that the node has the given x cordinate.
  28.     void print_level(asciinode *node, int x, int level)
  29.     {
  30.       int i, isleft;
  31.       if (node == NULL) return;
  32.       isleft = (node->parent_dir == -1);
  33.       if (level == 0)
  34.       {
  35.         for (i=0; i<(x-print_next-((node->lablen-isleft)/2)); i++)
  36.         {
  37.           printf(" ");
  38.         }
  39.         print_next += i;
  40.         printf("%s", node->label);
  41.         print_next += node->lablen;
  42.       }
  43.       else if (node->edge_length >= level)
  44.       {
  45.         if (node->left != NULL)
  46.         {
  47.           for (i=0; i<(x-print_next-(level)); i++)
  48.           {
  49.             printf(" ");
  50.           }
  51.           print_next += i;
  52.           printf("/");
  53.           print_next++;
  54.         }
  55.         if (node->right != NULL)
  56.         {
  57.           for (i=0; i<(x-print_next+(level)); i++)
  58.           {
  59.             printf(" ");
  60.           }
  61.           print_next += i;
  62.           printf("\\");
  63.           print_next++;
  64.         }
  65.       }
  66.       else
  67.       {
  68.         print_level(node->left,
  69.                     x-node->edge_length-1,
  70.                     level-node->edge_length-1);
  71.         print_level(node->right,
  72.                     x+node->edge_length+1,
  73.                     level-node->edge_length-1);
  74.       }
  75.     }
  76.      
  77.      
  78.     //This function fills in the edge_length and
  79.     //height fields of the specified tree
  80.     void compute_edge_lengths(asciinode *node)
  81.     {
  82.       int h, hmin, i, delta;
  83.       if (node == NULL) return;
  84.       compute_edge_lengths(node->left);
  85.       compute_edge_lengths(node->right);
  86.      
  87.       /* first fill in the edge_length of node */
  88.       if (node->right == NULL && node->left == NULL)
  89.       {
  90.         node->edge_length = 0;
  91.       }
  92.       else
  93.       {
  94.         if (node->left != NULL)
  95.         {
  96.           for (i=0; i<node->left->height && i < MAX_HEIGHT; i++)
  97.           {
  98.             rprofile[i] = -INFINITY;
  99.           }
  100.           compute_rprofile(node->left, 0, 0);
  101.           hmin = node->left->height;
  102.         }
  103.         else
  104.         {
  105.           hmin = 0;
  106.         }
  107.         if (node->right != NULL)
  108.         {
  109.           for (i=0; i<node->right->height && i < MAX_HEIGHT; i++)
  110.           {
  111.             lprofile[i] = INFINITY;
  112.           }
  113.           compute_lprofile(node->right, 0, 0);
  114.           hmin = MIN(node->right->height, hmin);
  115.         }
  116.         else
  117.         {
  118.           hmin = 0;
  119.         }
  120.         delta = 4;
  121.         for (i=0; i<hmin; i++)
  122.         {
  123.           delta = MAX(delta, gap + 1 + rprofile[i] - lprofile[i]);
  124.         }
  125.      
  126.         //If the node has two children of height 1, then we allow the
  127.         //two leaves to be within 1, instead of 2
  128.         if (((node->left != NULL && node->left->height == 1) ||
  129.               (node->right != NULL && node->right->height == 1))&&delta>4)
  130.         {
  131.           delta--;
  132.         }
  133.      
  134.         node->edge_length = ((delta+1)/2) - 1;
  135.       }
  136.      
  137.       //now fill in the height of node
  138.       h = 1;
  139.       if (node->left != NULL)
  140.       {
  141.         h = MAX(node->left->height + node->edge_length + 1, h);
  142.       }
  143.       if (node->right != NULL)
  144.       {
  145.         h = MAX(node->right->height + node->edge_length + 1, h);
  146.       }
  147.       node->height = h;
  148.     }
  149.  
  150.     asciinode * build_ascii_tree_recursive(Tree * t)
  151.     {
  152.       asciinode * node;
  153.      
  154.       if (t == NULL) return NULL;
  155.      
  156.       node = malloc(sizeof(asciinode));
  157.       node->left = build_ascii_tree_recursive(t->left);
  158.       node->right = build_ascii_tree_recursive(t->right);
  159.      
  160.       if (node->left != NULL)
  161.       {
  162.         node->left->parent_dir = -1;
  163.       }
  164.      
  165.       if (node->right != NULL)
  166.       {
  167.         node->right->parent_dir = 1;
  168.       }
  169.      
  170.       sprintf(node->label, "%d", t->element);
  171.       node->lablen = strlen(node->label);
  172.      
  173.       return node;
  174.     }
  175.      
  176.      
  177.     //Copy the tree into the ascii node structre
  178.     asciinode * build_ascii_tree(Tree * t)
  179.     {
  180.       asciinode *node;
  181.       if (t == NULL) return NULL;
  182.       node = build_ascii_tree_recursive(t);
  183.       node->parent_dir = 0;
  184.       return node;
  185.     }
  186.      
  187.     //Free all the nodes of the given tree
  188.     void free_ascii_tree(asciinode *node)
  189.     {
  190.       if (node == NULL) return;
  191.       free_ascii_tree(node->left);
  192.       free_ascii_tree(node->right);
  193.       free(node);
  194.     }
  195.      
  196.     //The following function fills in the lprofile array for the given tree.
  197.     //It assumes that the center of the label of the root of this tree
  198.     //is located at a position (x,y).  It assumes that the edge_length
  199.     //fields have been computed for this tree.
  200.     void compute_lprofile(asciinode *node, int x, int y)
  201.     {
  202.       int i, isleft;
  203.       if (node == NULL) return;
  204.       isleft = (node->parent_dir == -1);
  205.       lprofile[y] = MIN(lprofile[y], x-((node->lablen-isleft)/2));
  206.       if (node->left != NULL)
  207.       {
  208.         for (i=1; i <= node->edge_length && y+i < MAX_HEIGHT; i++)
  209.         {
  210.           lprofile[y+i] = MIN(lprofile[y+i], x-i);
  211.         }
  212.       }
  213.       compute_lprofile(node->left, x-node->edge_length-1, y+node->edge_length+1);
  214.       compute_lprofile(node->right, x+node->edge_length+1, y+node->edge_length+1);
  215.     }
  216.      
  217.     void compute_rprofile(asciinode *node, int x, int y)
  218.     {
  219.       int i, notleft;
  220.       if (node == NULL) return;
  221.       notleft = (node->parent_dir != -1);
  222.       rprofile[y] = MAX(rprofile[y], x+((node->lablen-notleft)/2));
  223.       if (node->right != NULL)
  224.       {
  225.         for (i=1; i <= node->edge_length && y+i < MAX_HEIGHT; i++)
  226.         {
  227.           rprofile[y+i] = MAX(rprofile[y+i], x+i);
  228.         }
  229.       }
  230.       compute_rprofile(node->left, x-node->edge_length-1, y+node->edge_length+1);
  231.       compute_rprofile(node->right, x+node->edge_length+1, y+node->edge_length+1);
  232.     }
  233.  
  234. Here is the asciii tree structure…
  235.  
  236.     struct asciinode_struct
  237.     {
  238.       asciinode * left, * right;
  239.      
  240.       //length of the edge from this node to its children
  241.       int edge_length;
  242.      
  243.       int height;      
  244.      
  245.       int lablen;
  246.      
  247.       //-1=I am left, 0=I am root, 1=right  
  248.       int parent_dir;  
  249.      
  250.       //max supported unit32 in dec, 10 digits max
  251.       char label[11];  
  252.     };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement