From cacf5445adea520945290c207af898eb36f411d9 Mon Sep 17 00:00:00 2001 From: heimoshuiyu Date: Wed, 26 May 2021 20:20:01 +0800 Subject: [PATCH] week13 format mowgli AVL --- week13/AVL.c | 370 ++++++++++++++++------------------- week13/AVL.h | 47 +++-- week13/main.c | 52 +++-- week13/printTree.c | 467 ++++++++++++++++++++------------------------- 4 files changed, 424 insertions(+), 512 deletions(-) diff --git a/week13/AVL.c b/week13/AVL.c index 8d1a38c..81b48c6 100644 --- a/week13/AVL.c +++ b/week13/AVL.c @@ -1,246 +1,208 @@ -#include #include "AVL.h" #include #include +#include #include -int max(int a, int b) -{ - if (a > b) - { - return a; - } +int max(int a, int b) { + if (a > b) { + return a; + } - return b; + return b; } -int getHeight(Node *N) -{ - if (N == NULL) - return -1; +int getHeight(Node *N) { + if (N == NULL) + return -1; - int x = getHeight(N->left); - int y = getHeight(N->right); + int x = getHeight(N->left); + int y = getHeight(N->right); - if (x >= y) - return x + 1; + if (x >= y) + return x + 1; - return y + 1; + return y + 1; } -int getBalance(Node *N) -{ - return getHeight(N->left) - getHeight(N->right); +int getBalance(Node *N) { return getHeight(N->left) - getHeight(N->right); } + +Node *findNode(Node *root, int x) { + if (root == NULL) { + return NULL; + } + + if (root->key == x) { + return root; + } + + if (x < root->key) { + return findNode(root->left, x); + } + + return findNode(root->right, x); } -Node *findNode(Node *root, int x) -{ - if (root == NULL) - { - return NULL; - } +Node *rightRotate(Node *N) { + Node *N1 = N->left; + Node *N2 = N1->right; - if (root->key == x) - { - return root; - } + N1->right = N; + N->left = N2; - if (x < root->key) - { - return findNode(root->left, x); - } + N->height = max(getHeight(N->left), getHeight(N->right)) + 1; + N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1; - return findNode(root->right, x); + return N1; } -Node *rightRotate(Node *N) -{ - Node *N1 = N->left; - Node *N2 = N1->right; +Node *leftRotate(Node *N) { + Node *N1 = N->right; + Node *N2 = N1->left; - N1->right = N; - N->left = N2; + N1->left = N; + N->right = N2; - N->height = max(getHeight(N->left), getHeight(N->right)) + 1; - N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1; + N->height = max(getHeight(N->left), getHeight(N->right)) + 1; + N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1; - return N1; + return N1; } -Node *leftRotate(Node *N) -{ - Node *N1 = N->right; - Node *N2 = N1->left; - - N1->left = N; - N->right = N2; - - N->height = max(getHeight(N->left), getHeight(N->right)) + 1; - N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1; - - return N1; +Node *minNode(Node *N) { + while (N->left != NULL) { + N = N->left; + } + return N; } -Node *minNode(Node *N) -{ - while (N->left != NULL) - { - N = N->left; - } - return N; +Node *insertNode(Node **root, int x) { + Node *ans; + + /* insert the data */ + if (*root == NULL) { + Node *temp = (Node *)malloc(sizeof(Node)); + temp->key = x; + temp->height = 0; + temp->left = NULL; + temp->right = NULL; + *root = temp; + ans = temp; + return ans; + } else if ((*root)->key > x) { + ans = insertNode(&(*root)->left, x); + } else if ((*root)->key < x) { + ans = insertNode(&(*root)->right, x); + } + + /* handle the unbalance problem */ + (*root)->height = + 1 + max(getHeight((*root)->left), getHeight((*root)->right)); + + int balance = getBalance(*root); + + /* case 1 left left unbalance */ + if (balance > 1 && getBalance((*root)->left) >= 0) { + *root = rightRotate(*root); + } + + /* case 2 left right unbalance */ + if (balance > 1 && getBalance((*root)->left) < 0) { + (*root)->left = leftRotate((*root)->left); + *root = rightRotate(*root); + } + + /* case 3 right left unbalance */ + if (balance < -1 && getBalance((*root)->right) > 0) { + (*root)->right = rightRotate((*root)->right); + *root = leftRotate(*root); + } + + /* case 4 right right unbalance */ + if (balance < -1 && getBalance((*root)->right) <= 0) { + *root = leftRotate(*root); + } + + return ans; } -Node *insertNode(Node **root, int x) -{ - Node *ans; +Node *deleteNode(Node **root, int x) { + Node *temp = *root; - /* insert the data */ - if (*root == NULL) - { - Node *temp = (Node *)malloc(sizeof(Node)); - temp->key = x; - temp->height = 0; - temp->left = NULL; - temp->right = NULL; - *root = temp; - ans = temp; - return ans; - } - else if ((*root)->key > x) - { - ans = insertNode(&(*root)->left, x); - } - else if ((*root)->key < x) - { - ans = insertNode(&(*root)->right, x); - } + if (*root == NULL) + return *root; - /* handle the unbalance problem */ - (*root)->height = 1 + max(getHeight((*root)->left), getHeight((*root)->right)); + if (x < (*root)->key) { + temp = deleteNode(&(*root)->left, x); + } - int balance = getBalance(*root); + else if (x > (*root)->key) { + temp = deleteNode(&(*root)->right, x); + } - /* case 1 left left unbalance */ - if (balance > 1 && getBalance((*root)->left) >= 0) - { - *root = rightRotate(*root); - } + else { + if ((*root)->left == NULL || (*root)->right == NULL) { + Node *child = (*root)->left != NULL ? (*root)->left : (*root)->right; - /* case 2 left right unbalance */ - if (balance > 1 && getBalance((*root)->left) < 0) - { - (*root)->left = leftRotate((*root)->left); - *root = rightRotate(*root); - } + if (child == NULL) { // no child case; + *root = NULL; + return temp; + } else { + (*root)->key = child->key; + if ((*root)->left && + (*root)->left->key == child->key) { // left child case; + temp = deleteNode(&(*root)->left, child->key); + } else if ((*root)->right && + (*root)->right->key == child->key) { // right child case; + temp = deleteNode(&(*root)->right, child->key); + } + } + } else { // two children case; + Node *child = minNode((*root)->right); + (*root)->key = child->key; + temp = deleteNode(&(*root)->right, child->key); + } + } - /* case 3 right left unbalance */ - if (balance < -1 && getBalance((*root)->right) > 0) - { - (*root)->right = rightRotate((*root)->right); - *root = leftRotate(*root); - } + if ((*root) == NULL) + return *root; - /* case 4 right right unbalance */ - if (balance < -1 && getBalance((*root)->right) <= 0) - { - *root = leftRotate(*root); - } + int balance = getBalance(*root); - return ans; + (*root)->height = + 1 + max(getHeight((*root)->left), getHeight((*root)->right)); + + /* case 1 left left unbalance */ + if (balance > 1 && getBalance((*root)->left) >= 0) { + *root = rightRotate(*root); + } + + /* case 2 left right unbalance */ + if (balance > 1 && getBalance((*root)->left) < 0) { + (*root)->left = leftRotate((*root)->left); + *root = rightRotate(*root); + } + + /* case 3 right left unbalance */ + if (balance < -1 && getBalance((*root)->right) > 0) { + (*root)->right = rightRotate((*root)->right); + *root = leftRotate(*root); + } + + /* case 4 right right unbalance */ + if (balance < -1 && getBalance((*root)->right) <= 0) { + *root = leftRotate(*root); + } + + return temp; } -Node *deleteNode(Node **root, int x) -{ - Node *temp = *root; +void destroyTree(Node *root) { + if (root == NULL) + return; - if (*root == NULL) - return *root; + destroyTree(root->left); + destroyTree(root->right); - if (x < (*root)->key) - { - temp = deleteNode(&(*root)->left, x); - } - - else if (x > (*root)->key) - { - temp = deleteNode(&(*root)->right, x); - } - - else - { - if ((*root)->left == NULL || (*root)->right == NULL) - { - Node *child = (*root)->left != NULL ? (*root)->left : (*root)->right; - - if (child == NULL) - { // no child case; - *root = NULL; - return temp; - } - else - { - (*root)->key = child->key; - if ((*root)->left && (*root)->left->key == child->key) - { // left child case; - temp = deleteNode(&(*root)->left, child->key); - } - else if ((*root)->right && (*root)->right->key == child->key) - { // right child case; - temp = deleteNode(&(*root)->right, child->key); - } - } - } - else - { // two children case; - Node *child = minNode((*root)->right); - (*root)->key = child->key; - temp = deleteNode(&(*root)->right, child->key); - } - } - - if ((*root) == NULL) - return *root; - - int balance = getBalance(*root); - - (*root)->height = 1 + max(getHeight((*root)->left), getHeight((*root)->right)); - - /* case 1 left left unbalance */ - if (balance > 1 && getBalance((*root)->left) >= 0) - { - *root = rightRotate(*root); - } - - /* case 2 left right unbalance */ - if (balance > 1 && getBalance((*root)->left) < 0) - { - (*root)->left = leftRotate((*root)->left); - *root = rightRotate(*root); - } - - /* case 3 right left unbalance */ - if (balance < -1 && getBalance((*root)->right) > 0) - { - (*root)->right = rightRotate((*root)->right); - *root = leftRotate(*root); - } - - /* case 4 right right unbalance */ - if (balance < -1 && getBalance((*root)->right) <= 0) - { - *root = leftRotate(*root); - } - - return temp; + free(root); } - -void destroyTree(Node *root) -{ - if (root == NULL) - return; - - destroyTree(root->left); - destroyTree(root->right); - - free(root); -} \ No newline at end of file diff --git a/week13/AVL.h b/week13/AVL.h index e434b11..8187e1c 100644 --- a/week13/AVL.h +++ b/week13/AVL.h @@ -1,59 +1,58 @@ typedef struct Node Node; -typedef struct Node -{ - int key, height; - Node *left, *right; +typedef struct Node { + int key, height; + Node *left, *right; } Node; Node *insertNode(Node **proot, int x); /* function: - inserts a new node to the tree + inserts a new node to the tree input: - proot - pointer to the pointer to the tree root - x - the key of the new node + proot - pointer to the pointer to the tree root + x - the key of the new node output: - returns a pointer to the newly inserted node - returns NULL if insertion is not successful + returns a pointer to the newly inserted node + returns NULL if insertion is not successful */ Node *deleteNode(Node **proot, int x); /* function: - removes a node from the tree without freeing it + removes a node from the tree without freeing it input: - proot - pointer to the pointer to the tree root - x - the key of of the node to be deleted + proot - pointer to the pointer to the tree root + x - the key of of the node to be deleted output: - returns a pointer to the deleted node - returns NULL if no such node exists + returns a pointer to the deleted node + returns NULL if no such node exists */ Node *findNode(Node *root, int x); /* function: - searches for a node in the tree + searches for a node in the tree input: - root - pointer to the tree root - x - the key of of the node to be searched + root - pointer to the tree root + x - the key of of the node to be searched output: - returns a pointer to the found node - returns NULL if no such node exists + returns a pointer to the found node + returns NULL if no such node exists */ void destroyTree(Node *root); /* function: - deletes all the nodes in the tree and frees the memory occupied by them + deletes all the nodes in the tree and frees the memory occupied by them input: - root - pointer to the tree node + root - pointer to the tree node */ void printTree(Node *root); /* function: - prints ascii tree for given Node structure - this function is already implemented in printTree.cpp + prints ascii tree for given Node structure + this function is already implemented in printTree.cpp input: - root - pointer to the tree node + root - pointer to the tree node */ diff --git a/week13/main.c b/week13/main.c index 59b459d..b199ab6 100644 --- a/week13/main.c +++ b/week13/main.c @@ -1,33 +1,31 @@ +#include "AVL.h" #include #include -#include "AVL.h" -int main() -{ - Node *root = NULL; +int main() { + Node *root = NULL; - int ins[] = {16, 10, 21, 5, 12, 18, 24, 2, 8, 11, 15, 19, 23, 31, 1, 6, 9, 13, 22, 7}; - int len = 20, x; - for (int i = 0; i < len; i++) - { - printf("\nAfter inserting key %d..\n", ins[i]); - insertNode(&root, ins[i]); - printTree(root); - } - printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); - scanf("%d", &x); - while (x) - { - if (x > 0) - insertNode(&root, x); - else - free(deleteNode(&root, -x)); - printTree(root); - printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); - scanf("%d", &x); - } + int ins[] = {16, 10, 21, 5, 12, 18, 24, 2, 8, 11, + 15, 19, 23, 31, 1, 6, 9, 13, 22, 7}; + int len = 20, x; + for (int i = 0; i < len; i++) { + printf("\nAfter inserting key %d..\n", ins[i]); + insertNode(&root, ins[i]); + printTree(root); + } + printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); + scanf("%d", &x); + while (x) { + if (x > 0) + insertNode(&root, x); + else + free(deleteNode(&root, -x)); + printTree(root); + printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); + scanf("%d", &x); + } - destroyTree(root); + destroyTree(root); - return 0; -} \ No newline at end of file + return 0; +} diff --git a/week13/printTree.c b/week13/printTree.c index ec94a03..05069a9 100644 --- a/week13/printTree.c +++ b/week13/printTree.c @@ -1,28 +1,27 @@ +#include "AVL.h" #include #include #include -#include "AVL.h" -//printing tree in ascii +// printing tree in ascii typedef struct asciinode_struct asciinode; -struct asciinode_struct -{ - asciinode *left, *right; +struct asciinode_struct { + asciinode *left, *right; - //length of the edge from this node to its children - int edge_length; + // length of the edge from this node to its children + int edge_length; - int height; + int height; - int lablen; + int lablen; - //-1=I am left, 0=I am root, 1=right - int parent_dir; + //-1=I am left, 0=I am root, 1=right + int parent_dir; - //max supported unit32 in dec, 10 digits max - char label[11]; + // max supported unit32 in dec, 10 digits max + char label[11]; }; #define MAX_HEIGHT 1000 @@ -30,266 +29,220 @@ int lprofile[MAX_HEIGHT]; int rprofile[MAX_HEIGHT]; #define INFINITY (1 << 20) -//adjust gap between left and right nodes +// adjust gap between left and right nodes int gap = 3; -//used for printing next node in the same level, -//this is the x coordinate of the next char printed +// used for printing next node in the same level, +// this is the x coordinate of the next char printed int print_next; -int MIN(int X, int Y) -{ - return ((X) < (Y)) ? (X) : (Y); +int MIN(int X, int Y) { return ((X) < (Y)) ? (X) : (Y); } + +int MAX(int X, int Y) { return ((X) > (Y)) ? (X) : (Y); } + +asciinode *build_ascii_tree_recursive(Node *t) { + asciinode *node; + + if (t == NULL) + return NULL; + + node = (asciinode *)malloc(sizeof(asciinode)); + node->left = build_ascii_tree_recursive(t->left); + node->right = build_ascii_tree_recursive(t->right); + + if (node->left != NULL) { + node->left->parent_dir = -1; + } + + if (node->right != NULL) { + node->right->parent_dir = 1; + } + + sprintf(node->label, "%d|%d", t->key, t->height); + + node->lablen = strlen(node->label); + + return node; } -int MAX(int X, int Y) -{ - return ((X) > (Y)) ? (X) : (Y); +// Copy the tree into the ascii node structre +asciinode *build_ascii_tree(Node *t) { + asciinode *node; + if (t == NULL) + return NULL; + node = build_ascii_tree_recursive(t); + node->parent_dir = 0; + return node; } -asciinode *build_ascii_tree_recursive(Node *t) -{ - asciinode *node; - - if (t == NULL) - return NULL; - - node = (asciinode *)malloc(sizeof(asciinode)); - node->left = build_ascii_tree_recursive(t->left); - node->right = build_ascii_tree_recursive(t->right); - - if (node->left != NULL) - { - node->left->parent_dir = -1; - } - - if (node->right != NULL) - { - node->right->parent_dir = 1; - } - - sprintf(node->label, "%d|%d", t->key, t->height); - - node->lablen = strlen(node->label); - - return node; +// Free all the nodes of the given tree +void free_ascii_tree(asciinode *node) { + if (node == NULL) + return; + free_ascii_tree(node->left); + free_ascii_tree(node->right); + free(node); } -//Copy the tree into the ascii node structre -asciinode *build_ascii_tree(Node *t) -{ - asciinode *node; - if (t == NULL) - return NULL; - node = build_ascii_tree_recursive(t); - node->parent_dir = 0; - return node; +// The following function fills in the lprofile array for the given tree. +// It assumes that the center of the label of the root of this tree +// is located at a position (x,y). It assumes that the edge_length +// fields have been computed for this tree. +void compute_lprofile(asciinode *node, int x, int y) { + int i, isleft; + if (node == NULL) + return; + isleft = (node->parent_dir == -1); + lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2)); + if (node->left != NULL) { + for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) { + lprofile[y + i] = MIN(lprofile[y + i], x - i); + } + } + compute_lprofile(node->left, x - node->edge_length - 1, + y + node->edge_length + 1); + compute_lprofile(node->right, x + node->edge_length + 1, + y + node->edge_length + 1); } -//Free all the nodes of the given tree -void free_ascii_tree(asciinode *node) -{ - if (node == NULL) - return; - free_ascii_tree(node->left); - free_ascii_tree(node->right); - free(node); +void compute_rprofile(asciinode *node, int x, int y) { + int i, notleft; + if (node == NULL) + return; + notleft = (node->parent_dir != -1); + rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2)); + if (node->right != NULL) { + for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) { + rprofile[y + i] = MAX(rprofile[y + i], x + i); + } + } + compute_rprofile(node->left, x - node->edge_length - 1, + y + node->edge_length + 1); + compute_rprofile(node->right, x + node->edge_length + 1, + y + node->edge_length + 1); } -//The following function fills in the lprofile array for the given tree. -//It assumes that the center of the label of the root of this tree -//is located at a position (x,y). It assumes that the edge_length -//fields have been computed for this tree. -void compute_lprofile(asciinode *node, int x, int y) -{ - int i, isleft; - if (node == NULL) - return; - isleft = (node->parent_dir == -1); - lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2)); - if (node->left != NULL) - { - for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) - { - lprofile[y + i] = MIN(lprofile[y + i], x - i); - } - } - compute_lprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1); - compute_lprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1); +// This function fills in the edge_length and +// height fields of the specified tree +void compute_edge_lengths(asciinode *node) { + int h, hmin, i, delta; + if (node == NULL) + return; + compute_edge_lengths(node->left); + compute_edge_lengths(node->right); + + /* first fill in the edge_length of node */ + if (node->right == NULL && node->left == NULL) { + node->edge_length = 0; + } else { + if (node->left != NULL) { + for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++) { + rprofile[i] = -INFINITY; + } + compute_rprofile(node->left, 0, 0); + hmin = node->left->height; + } else { + hmin = 0; + } + if (node->right != NULL) { + for (i = 0; i < node->right->height && i < MAX_HEIGHT; i++) { + lprofile[i] = INFINITY; + } + compute_lprofile(node->right, 0, 0); + hmin = MIN(node->right->height, hmin); + } else { + hmin = 0; + } + delta = 4; + for (i = 0; i < hmin; i++) { + delta = MAX(delta, gap + 1 + rprofile[i] - lprofile[i]); + } + + // If the node has two children of height 1, then we allow the + // two leaves to be within 1, instead of 2 + if (((node->left != NULL && node->left->height == 1) || + (node->right != NULL && node->right->height == 1)) && + delta > 4) { + delta--; + } + + node->edge_length = ((delta + 1) / 2) - 1; + } + + // now fill in the height of node + h = 1; + if (node->left != NULL) { + h = MAX(node->left->height + node->edge_length + 1, h); + } + if (node->right != NULL) { + h = MAX(node->right->height + node->edge_length + 1, h); + } + node->height = h; } -void compute_rprofile(asciinode *node, int x, int y) -{ - int i, notleft; - if (node == NULL) - return; - notleft = (node->parent_dir != -1); - rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2)); - if (node->right != NULL) - { - for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) - { - rprofile[y + i] = MAX(rprofile[y + i], x + i); - } - } - compute_rprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1); - compute_rprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1); +// This function prints the given level of the given tree, assuming +// that the node has the given x cordinate. +void print_level(asciinode *node, int x, int level) { + int i, isleft; + if (node == NULL) + return; + isleft = (node->parent_dir == -1); + if (level == 0) { + for (i = 0; i < (x - print_next - ((node->lablen - isleft) / 2)); i++) { + printf(" "); + } + print_next += i; + printf("%s", node->label); + print_next += node->lablen; + } else if (node->edge_length >= level) { + if (node->left != NULL) { + for (i = 0; i < (x - print_next - (level)); i++) { + printf(" "); + } + print_next += i; + printf("/"); + print_next++; + } + if (node->right != NULL) { + for (i = 0; i < (x - print_next + (level)); i++) { + printf(" "); + } + print_next += i; + printf("\\"); + print_next++; + } + } else { + print_level(node->left, x - node->edge_length - 1, + level - node->edge_length - 1); + print_level(node->right, x + node->edge_length + 1, + level - node->edge_length - 1); + } } -//This function fills in the edge_length and -//height fields of the specified tree -void compute_edge_lengths(asciinode *node) -{ - int h, hmin, i, delta; - if (node == NULL) - return; - compute_edge_lengths(node->left); - compute_edge_lengths(node->right); - - /* first fill in the edge_length of node */ - if (node->right == NULL && node->left == NULL) - { - node->edge_length = 0; - } - else - { - if (node->left != NULL) - { - for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++) - { - rprofile[i] = -INFINITY; - } - compute_rprofile(node->left, 0, 0); - hmin = node->left->height; - } - else - { - hmin = 0; - } - if (node->right != NULL) - { - for (i = 0; i < node->right->height && i < MAX_HEIGHT; i++) - { - lprofile[i] = INFINITY; - } - compute_lprofile(node->right, 0, 0); - hmin = MIN(node->right->height, hmin); - } - else - { - hmin = 0; - } - delta = 4; - for (i = 0; i < hmin; i++) - { - delta = MAX(delta, gap + 1 + rprofile[i] - lprofile[i]); - } - - //If the node has two children of height 1, then we allow the - //two leaves to be within 1, instead of 2 - if (((node->left != NULL && node->left->height == 1) || - (node->right != NULL && node->right->height == 1)) && - delta > 4) - { - delta--; - } - - node->edge_length = ((delta + 1) / 2) - 1; - } - - //now fill in the height of node - h = 1; - if (node->left != NULL) - { - h = MAX(node->left->height + node->edge_length + 1, h); - } - if (node->right != NULL) - { - h = MAX(node->right->height + node->edge_length + 1, h); - } - node->height = h; +// prints ascii tree for given Node structure +void printTree(Node *root) { + asciinode *proot; + int xmin, i; + if (root == NULL) + return; + proot = build_ascii_tree(root); + compute_edge_lengths(proot); + for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) { + lprofile[i] = INFINITY; + } + compute_lprofile(proot, 0, 0); + xmin = 0; + for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) { + xmin = MIN(xmin, lprofile[i]); + } + for (i = 0; i < proot->height; i++) { + print_next = 0; + print_level(proot, -xmin, i); + printf("\n"); + } + if (proot->height >= MAX_HEIGHT) { + printf("(This tree is taller than %d, and may be drawn incorrectly.)\n", + MAX_HEIGHT); + } + free_ascii_tree(proot); } - -//This function prints the given level of the given tree, assuming -//that the node has the given x cordinate. -void print_level(asciinode *node, int x, int level) -{ - int i, isleft; - if (node == NULL) - return; - isleft = (node->parent_dir == -1); - if (level == 0) - { - for (i = 0; i < (x - print_next - ((node->lablen - isleft) / 2)); i++) - { - printf(" "); - } - print_next += i; - printf("%s", node->label); - print_next += node->lablen; - } - else if (node->edge_length >= level) - { - if (node->left != NULL) - { - for (i = 0; i < (x - print_next - (level)); i++) - { - printf(" "); - } - print_next += i; - printf("/"); - print_next++; - } - if (node->right != NULL) - { - for (i = 0; i < (x - print_next + (level)); i++) - { - printf(" "); - } - print_next += i; - printf("\\"); - print_next++; - } - } - else - { - print_level(node->left, - x - node->edge_length - 1, - level - node->edge_length - 1); - print_level(node->right, - x + node->edge_length + 1, - level - node->edge_length - 1); - } -} - -//prints ascii tree for given Node structure -void printTree(Node *root) -{ - asciinode *proot; - int xmin, i; - if (root == NULL) - return; - proot = build_ascii_tree(root); - compute_edge_lengths(proot); - for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) - { - lprofile[i] = INFINITY; - } - compute_lprofile(proot, 0, 0); - xmin = 0; - for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) - { - xmin = MIN(xmin, lprofile[i]); - } - for (i = 0; i < proot->height; i++) - { - print_next = 0; - print_level(proot, -xmin, i); - printf("\n"); - } - if (proot->height >= MAX_HEIGHT) - { - printf("(This tree is taller than %d, and may be drawn incorrectly.)\n", MAX_HEIGHT); - } - free_ascii_tree(proot); -} \ No newline at end of file