Advertisement
alien_fx_fiend

Binary Tree Print (Original C Code Needs Fixing)

Nov 2nd, 2024
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.05 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4. #include <time.h>
  5. #include <string.h>
  6. #include <math.h>
  7.  
  8. #define MAX_HEIGHT 1000
  9. #define INFINITY (1<<20)
  10.  
  11. struct tree {
  12.     int key;
  13.     struct tree* left;
  14.     struct tree* right;
  15. };
  16.  
  17. typedef struct asciiNode {
  18.     struct asciiNode* left;
  19.     struct asciiNode* right;
  20.     int edge_length;
  21.     int height;
  22.     int lablen;
  23.     int parent_dir;    // -1=left, 0=root, 1=right
  24.     char label[11];    // Max label length of 10 chars + terminator
  25. } asciiNode;
  26.  
  27. int MAX(int x, int y) { return ((x) > (y)) ? (x) : (y); }
  28. int MIN(int x, int y) { return ((x) < (y)) ? (x) : (y); }
  29.  
  30. // Get the maximum height of the tree
  31. int getMaxHeight(struct tree* n) {
  32.     if (n == NULL) return 0;
  33.     int leftHeight = getMaxHeight(n->left);
  34.     int rightHeight = getMaxHeight(n->right);
  35.     return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
  36. }
  37.  
  38. // Convert integer to string
  39. int intToString(int val, char* buff) {
  40.     sprintf(buff, "%d", val);
  41.     return strlen(buff);
  42. }
  43.  
  44. // Print the arm branches (eg, /    \ ) between nodes
  45. void printBranches(int branchLen, int nodeSpacing, int startLen, int nodesInThisLevel, const asciiNode** nodesQueue, FILE* out) {
  46.     int i, j;
  47.     for (i = 0; i < nodesInThisLevel / 2; i++) {
  48.         for (j = 0; j < startLen - 1; j++) fprintf(out, " ");
  49.         if (nodesQueue[i * 2] != NULL) {
  50.             fprintf(out, "/");
  51.         }
  52.         else {
  53.             fprintf(out, " ");
  54.         }
  55.         for (j = 0; j < branchLen - 1; j++) fprintf(out, " ");
  56.         if (nodesQueue[i * 2 + 1] != NULL) {
  57.             fprintf(out, "\\");
  58.         }
  59.         else {
  60.             fprintf(out, " ");
  61.         }
  62.         for (j = 0; j < nodeSpacing - 2; j++) fprintf(out, " ");
  63.     }
  64.     fprintf(out, "\n");
  65. }
  66.  
  67. // Print the branches and node (eg, ___10___ )
  68. void printNodes(int branchLen, int nodeSpacing, int startLen, int nodesInThisLevel, const asciiNode** nodesQueue, FILE* out) {
  69.     int i, j;
  70.     for (i = 0; i < nodesInThisLevel; i++) {
  71.         for (j = 0; j < startLen; j++) fprintf(out, " ");
  72.         if (nodesQueue[i] == NULL) {
  73.             for (j = 0; j < branchLen + 2; j++) fprintf(out, " ");
  74.             continue;
  75.         }
  76.         if (strlen(nodesQueue[i]->label) == 1)
  77.             fprintf(out, "%s", nodesQueue[i]->label);
  78.         else
  79.             fprintf(out, "%s", nodesQueue[i]->label);
  80.         for (j = 0; j < nodeSpacing; j++) fprintf(out, " ");
  81.     }
  82.     fprintf(out, "\n");
  83. }
  84.  
  85. struct tree* treeMakeRandom(int lo, int hi) {
  86.     struct tree* t;
  87.     if (hi <= lo) {
  88.         return 0;
  89.     }
  90.     else {
  91.         int mid = lo + rand() % (hi - lo);
  92.         t = (struct tree*)malloc(sizeof(struct tree));
  93.         t->key = mid;
  94.         t->left = treeMakeRandom(lo, mid);
  95.         t->right = treeMakeRandom(mid + 1, hi);
  96.         return t;
  97.     }
  98. }
  99.  
  100. asciiNode* createAsciiNode() {
  101.     asciiNode* node = malloc(sizeof(asciiNode));
  102.     node->left = NULL;
  103.     node->right = NULL;
  104.     node->edge_length = 0;
  105.     node->height = 0;
  106.     node->lablen = 0;
  107.     node->parent_dir = 0;
  108.     return node;
  109. }
  110.  
  111. // Convert the binary tree to ASCII tree
  112. asciiNode* buildAsciiTreeRecursive(struct tree* t) {
  113.     if (t == NULL) return NULL;
  114.  
  115.     asciiNode* node = createAsciiNode();
  116.     node->left = buildAsciiTreeRecursive(t->left);
  117.     node->right = buildAsciiTreeRecursive(t->right);
  118.  
  119.     if (node->left) node->left->parent_dir = -1;
  120.     if (node->right) node->right->parent_dir = 1;
  121.  
  122.     sprintf(node->label, "%d", t->key);
  123.     node->lablen = strlen(node->label);
  124.  
  125.     return node;
  126. }
  127.  
  128. asciiNode* buildAsciiTree(struct tree* t) {
  129.     if (t == NULL) return NULL;
  130.     asciiNode* node = buildAsciiTreeRecursive(t);
  131.     node->parent_dir = 0;
  132.     return node;
  133. }
  134.  
  135. // The following function fills in the lprofile array for the given tree.
  136. // It assumes that the center of the label of the root of this tree
  137. // is located at a position (x,y).  It assumes that the edge_length
  138. // fields have been computed for this tree.
  139. void computeLprofile(asciiNode* node, int x, int y, int* lprofile) {
  140.     if (node == NULL) return;
  141.     int isleft = (node->parent_dir == -1);
  142.     lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2));
  143.     if (node->left != NULL) {
  144.         for (int i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) {
  145.             lprofile[y + i] = MIN(lprofile[y + i], x - i);
  146.         }
  147.     }
  148.     computeLprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1, lprofile);
  149.     computeLprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1, lprofile);
  150. }
  151.  
  152. void computeRprofile(asciiNode* node, int x, int y, int* rprofile) {
  153.     if (node == NULL) return;
  154.     int notleft = (node->parent_dir != -1);
  155.     rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2));
  156.     if (node->right != NULL) {
  157.         for (int i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) {
  158.             rprofile[y + i] = MAX(rprofile[y + i], x + i);
  159.         }
  160.     }
  161.     computeRprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1, rprofile);
  162.     computeRprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1, rprofile);
  163. }
  164.  
  165. // Compute the gap between two subtrees
  166. int getGap(asciiNode* leftRoot, asciiNode* rightRoot) {
  167.     int i, j;
  168.     int* lprofile = malloc(sizeof(int) * MAX_HEIGHT);
  169.     int* rprofile = malloc(sizeof(int) * MAX_HEIGHT);
  170.     int gap = 0;
  171.  
  172.     for (i = 0; i < MAX_HEIGHT; i++) {
  173.         lprofile[i] = INFINITY;
  174.         rprofile[i] = -INFINITY;
  175.     }
  176.  
  177.     computeLprofile(leftRoot, 0, 0, lprofile);
  178.     computeRprofile(rightRoot, 0, 0, rprofile);
  179.  
  180.     for (i = 0; i < MAX_HEIGHT; i++) {
  181.         gap = MAX(gap, lprofile[i] - rprofile[i]);
  182.     }
  183.  
  184.     free(lprofile);
  185.     free(rprofile);
  186.     return gap + 1;
  187. }
  188.  
  189. void computeEdgeLengths(asciiNode* node) {
  190.     if (node == NULL) return;
  191.     computeEdgeLengths(node->left);
  192.     computeEdgeLengths(node->right);
  193.  
  194.     // Initialize min_height and delta
  195.     int min_height = MIN(
  196.         node->left ? node->left->height : 0,
  197.         node->right ? node->right->height : 0);
  198.     int delta = 4;
  199.  
  200.     // Set edge_length for this node
  201.     node->edge_length = ((delta + min_height) / 2) - 1;
  202. }
  203.  
  204. void printLevel(asciiNode* node, int x, int level) {
  205.     if (node == NULL) return;
  206.     int i, isleft = (node->parent_dir == -1);
  207.  
  208.     if (level == 0) {
  209.         for (i = 0; i < (x - node->lablen) / 2; i++) printf(" ");
  210.         printf("%s", node->label);
  211.         for (i = 0; i < (x - node->lablen + 1) / 2; i++) printf(" ");
  212.     }
  213.     else if (node->edge_length >= level) {
  214.         if (node->left != NULL) {
  215.             for (i = 0; i < (x - 2) / 2; i++) printf(" ");
  216.             printf("/");
  217.             for (i = 0; i < (x - 2) / 2 + 1; i++) printf(" ");
  218.         }
  219.         else {
  220.             for (i = 0; i < x; i++) printf(" ");
  221.         }
  222.  
  223.         if (node->right != NULL) {
  224.             for (i = 0; i < (x - 2) / 2; i++) printf(" ");
  225.             printf("\\");
  226.             for (i = 0; i < (x - 2) / 2 + 1; i++) printf(" ");
  227.         }
  228.         else {
  229.             for (i = 0; i < x; i++) printf(" ");
  230.         }
  231.     }
  232.     else {
  233.         printLevel(node->left, x / 2, level - node->edge_length - 1);
  234.         printLevel(node->right, x / 2, level - node->edge_length - 1);
  235.     }
  236. }
  237.  
  238. void printTree(struct tree* t) {
  239.     if (t == NULL) return;
  240.  
  241.     asciiNode* proot = buildAsciiTree(t);
  242.     computeEdgeLengths(proot);
  243.  
  244.     // Compute height of the tree
  245.     int h = proot->height;
  246.  
  247.     // Width of the tree, adjusted for better spacing
  248.     int w = pow(2, h) * 2 - 1;
  249.  
  250.     // Print each level
  251.     for (int i = 0; i <= h; i++) {
  252.         printLevel(proot, w, i);
  253.         printf("\n");
  254.     }
  255. }
  256.  
  257. int treeSize(const struct tree* t) {
  258.     if (t == 0) {
  259.         return 0;
  260.     }
  261.     else {
  262.         return 1 + treeSize(t->left) + treeSize(t->right);
  263.     }
  264. }
  265.  
  266. int treeHeight(const struct tree* t) {
  267.     if (t == 0) {
  268.         return -1;
  269.     }
  270.     else {
  271.         int l = treeHeight(t->left);
  272.         int r = treeHeight(t->right);
  273.         return 1 + ((l > r) ? l : r);
  274.     }
  275. }
  276.  
  277. void freeAsciiTree(asciiNode* node) {
  278.     if (node == NULL) return;
  279.     freeAsciiTree(node->left);
  280.     freeAsciiTree(node->right);
  281.     free(node);
  282. }
  283.  
  284. void freeTree(struct tree* t) {
  285.     if (t != NULL) {
  286.         freeTree(t->left);
  287.         freeTree(t->right);
  288.         free(t);
  289.     }
  290. }
  291.  
  292. int main() {
  293.     int n;
  294.     printf("Enter the maximum value for the tree (n): ");
  295.     if (scanf("%d", &n) != 1 || n <= 0) {
  296.         fprintf(stderr, "Invalid input. Please enter a positive number.\n");
  297.         return 1;
  298.     }
  299.  
  300.     srand(time(0));
  301.  
  302.     struct tree* t = treeMakeRandom(0, n);
  303.     printf("\nBinary Search Tree:\n");
  304.     printTree(t);
  305.     printf("\nSize = %d\n", treeSize(t));
  306.     printf("Height = %d\n", treeHeight(t));
  307.  
  308.     // Clean up
  309.     freeTree(t);
  310.  
  311.     // Pause the console
  312.     printf("\nPress Enter to continue...");
  313.     getchar(); // Consume the newline from scanf
  314.     getchar(); // Wait for Enter key
  315.  
  316.     return 0;
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement