week13 format mowgli AVL

This commit is contained in:
2021-05-26 20:20:01 +08:00
parent 679b38ab78
commit cacf5445ad
4 changed files with 424 additions and 512 deletions

View File

@@ -1,246 +1,208 @@
#include <stdio.h>
#include "AVL.h" #include "AVL.h"
#include <malloc.h> #include <malloc.h>
#include <math.h> #include <math.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
int max(int a, int b) int max(int a, int b) {
{ if (a > b) {
if (a > b) return a;
{ }
return a;
}
return b; return b;
} }
int getHeight(Node *N) int getHeight(Node *N) {
{ if (N == NULL)
if (N == NULL) return -1;
return -1;
int x = getHeight(N->left); int x = getHeight(N->left);
int y = getHeight(N->right); int y = getHeight(N->right);
if (x >= y) if (x >= y)
return x + 1; return x + 1;
return y + 1; return y + 1;
} }
int getBalance(Node *N) int getBalance(Node *N) { return getHeight(N->left) - getHeight(N->right); }
{
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) Node *rightRotate(Node *N) {
{ Node *N1 = N->left;
if (root == NULL) Node *N2 = N1->right;
{
return NULL;
}
if (root->key == x) N1->right = N;
{ N->left = N2;
return root;
}
if (x < root->key) N->height = max(getHeight(N->left), getHeight(N->right)) + 1;
{ N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1;
return findNode(root->left, x);
}
return findNode(root->right, x); return N1;
} }
Node *rightRotate(Node *N) Node *leftRotate(Node *N) {
{ Node *N1 = N->right;
Node *N1 = N->left; Node *N2 = N1->left;
Node *N2 = N1->right;
N1->right = N; N1->left = N;
N->left = N2; N->right = N2;
N->height = max(getHeight(N->left), getHeight(N->right)) + 1; N->height = max(getHeight(N->left), getHeight(N->right)) + 1;
N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1; N1->height = max(getHeight(N1->left), getHeight(N1->right)) + 1;
return N1; return N1;
} }
Node *leftRotate(Node *N) Node *minNode(Node *N) {
{ while (N->left != NULL) {
Node *N1 = N->right; N = N->left;
Node *N2 = N1->left; }
return N;
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) Node *insertNode(Node **root, int x) {
{ Node *ans;
while (N->left != NULL)
{ /* insert the data */
N = N->left; if (*root == NULL) {
} Node *temp = (Node *)malloc(sizeof(Node));
return N; 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 *deleteNode(Node **root, int x) {
{ Node *temp = *root;
Node *ans;
/* insert the data */ if (*root == NULL)
if (*root == NULL) return *root;
{
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 */ if (x < (*root)->key) {
(*root)->height = 1 + max(getHeight((*root)->left), getHeight((*root)->right)); temp = deleteNode(&(*root)->left, x);
}
int balance = getBalance(*root); else if (x > (*root)->key) {
temp = deleteNode(&(*root)->right, x);
}
/* case 1 left left unbalance */ else {
if (balance > 1 && getBalance((*root)->left) >= 0) if ((*root)->left == NULL || (*root)->right == NULL) {
{ Node *child = (*root)->left != NULL ? (*root)->left : (*root)->right;
*root = rightRotate(*root);
}
/* case 2 left right unbalance */ if (child == NULL) { // no child case;
if (balance > 1 && getBalance((*root)->left) < 0) *root = NULL;
{ return temp;
(*root)->left = leftRotate((*root)->left); } else {
*root = rightRotate(*root); (*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 ((*root) == NULL)
if (balance < -1 && getBalance((*root)->right) > 0) return *root;
{
(*root)->right = rightRotate((*root)->right);
*root = leftRotate(*root);
}
/* case 4 right right unbalance */ int balance = getBalance(*root);
if (balance < -1 && getBalance((*root)->right) <= 0)
{
*root = leftRotate(*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) void destroyTree(Node *root) {
{ if (root == NULL)
Node *temp = *root; return;
if (*root == NULL) destroyTree(root->left);
return *root; destroyTree(root->right);
if (x < (*root)->key) free(root);
{
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;
} }
void destroyTree(Node *root)
{
if (root == NULL)
return;
destroyTree(root->left);
destroyTree(root->right);
free(root);
}

View File

@@ -1,59 +1,58 @@
typedef struct Node Node; typedef struct Node Node;
typedef struct Node typedef struct Node {
{ int key, height;
int key, height; Node *left, *right;
Node *left, *right;
} Node; } Node;
Node *insertNode(Node **proot, int x); Node *insertNode(Node **proot, int x);
/* /*
function: function:
inserts a new node to the tree inserts a new node to the tree
input: input:
proot - pointer to the pointer to the tree root proot - pointer to the pointer to the tree root
x - the key of the new node x - the key of the new node
output: output:
returns a pointer to the newly inserted node returns a pointer to the newly inserted node
returns NULL if insertion is not successful returns NULL if insertion is not successful
*/ */
Node *deleteNode(Node **proot, int x); Node *deleteNode(Node **proot, int x);
/* /*
function: function:
removes a node from the tree without freeing it removes a node from the tree without freeing it
input: input:
proot - pointer to the pointer to the tree root proot - pointer to the pointer to the tree root
x - the key of of the node to be deleted x - the key of of the node to be deleted
output: output:
returns a pointer to the deleted node returns a pointer to the deleted node
returns NULL if no such node exists returns NULL if no such node exists
*/ */
Node *findNode(Node *root, int x); Node *findNode(Node *root, int x);
/* /*
function: function:
searches for a node in the tree searches for a node in the tree
input: input:
root - pointer to the tree root root - pointer to the tree root
x - the key of of the node to be searched x - the key of of the node to be searched
output: output:
returns a pointer to the found node returns a pointer to the found node
returns NULL if no such node exists returns NULL if no such node exists
*/ */
void destroyTree(Node *root); void destroyTree(Node *root);
/* /*
function: 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: input:
root - pointer to the tree node root - pointer to the tree node
*/ */
void printTree(Node *root); void printTree(Node *root);
/* /*
function: function:
prints ascii tree for given Node structure prints ascii tree for given Node structure
this function is already implemented in printTree.cpp this function is already implemented in printTree.cpp
input: input:
root - pointer to the tree node root - pointer to the tree node
*/ */

View File

@@ -1,33 +1,31 @@
#include "AVL.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "AVL.h"
int main() int main() {
{ Node *root = NULL;
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 ins[] = {16, 10, 21, 5, 12, 18, 24, 2, 8, 11,
int len = 20, x; 15, 19, 23, 31, 1, 6, 9, 13, 22, 7};
for (int i = 0; i < len; i++) int len = 20, x;
{ for (int i = 0; i < len; i++) {
printf("\nAfter inserting key %d..\n", ins[i]); printf("\nAfter inserting key %d..\n", ins[i]);
insertNode(&root, ins[i]); insertNode(&root, ins[i]);
printTree(root); printTree(root);
} }
printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): ");
scanf("%d", &x); scanf("%d", &x);
while (x) while (x) {
{ if (x > 0)
if (x > 0) insertNode(&root, x);
insertNode(&root, x); else
else free(deleteNode(&root, -x));
free(deleteNode(&root, -x)); printTree(root);
printTree(root); printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): ");
printf("\nInsert a new node (+ to insert, - to delete, 0 to exit): "); scanf("%d", &x);
scanf("%d", &x); }
}
destroyTree(root); destroyTree(root);
return 0; return 0;
} }

View File

@@ -1,28 +1,27 @@
#include "AVL.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "AVL.h"
//printing tree in ascii // printing tree in ascii
typedef struct asciinode_struct asciinode; typedef struct asciinode_struct asciinode;
struct asciinode_struct struct asciinode_struct {
{ asciinode *left, *right;
asciinode *left, *right;
//length of the edge from this node to its children // length of the edge from this node to its children
int edge_length; int edge_length;
int height; int height;
int lablen; int lablen;
//-1=I am left, 0=I am root, 1=right //-1=I am left, 0=I am root, 1=right
int parent_dir; int parent_dir;
//max supported unit32 in dec, 10 digits max // max supported unit32 in dec, 10 digits max
char label[11]; char label[11];
}; };
#define MAX_HEIGHT 1000 #define MAX_HEIGHT 1000
@@ -30,266 +29,220 @@ int lprofile[MAX_HEIGHT];
int rprofile[MAX_HEIGHT]; int rprofile[MAX_HEIGHT];
#define INFINITY (1 << 20) #define INFINITY (1 << 20)
//adjust gap between left and right nodes // adjust gap between left and right nodes
int gap = 3; int gap = 3;
//used for printing next node in the same level, // used for printing next node in the same level,
//this is the x coordinate of the next char printed // this is the x coordinate of the next char printed
int print_next; int print_next;
int MIN(int X, int Y) int MIN(int X, int Y) { return ((X) < (Y)) ? (X) : (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) // Copy the tree into the ascii node structre
{ asciinode *build_ascii_tree(Node *t) {
return ((X) > (Y)) ? (X) : (Y); 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) // Free all the nodes of the given tree
{ void free_ascii_tree(asciinode *node) {
asciinode *node; if (node == NULL)
return;
if (t == NULL) free_ascii_tree(node->left);
return NULL; free_ascii_tree(node->right);
free(node);
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;
} }
//Copy the tree into the ascii node structre // The following function fills in the lprofile array for the given tree.
asciinode *build_ascii_tree(Node *t) // 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
asciinode *node; // fields have been computed for this tree.
if (t == NULL) void compute_lprofile(asciinode *node, int x, int y) {
return NULL; int i, isleft;
node = build_ascii_tree_recursive(t); if (node == NULL)
node->parent_dir = 0; return;
return node; 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 compute_rprofile(asciinode *node, int x, int y) {
void free_ascii_tree(asciinode *node) int i, notleft;
{ if (node == NULL)
if (node == NULL) return;
return; notleft = (node->parent_dir != -1);
free_ascii_tree(node->left); rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2));
free_ascii_tree(node->right); if (node->right != NULL) {
free(node); 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. // This function fills in the edge_length and
//It assumes that the center of the label of the root of this tree // height fields of the specified tree
//is located at a position (x,y). It assumes that the edge_length void compute_edge_lengths(asciinode *node) {
//fields have been computed for this tree. int h, hmin, i, delta;
void compute_lprofile(asciinode *node, int x, int y) if (node == NULL)
{ return;
int i, isleft; compute_edge_lengths(node->left);
if (node == NULL) compute_edge_lengths(node->right);
return;
isleft = (node->parent_dir == -1); /* first fill in the edge_length of node */
lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2)); if (node->right == NULL && node->left == NULL) {
if (node->left != NULL) node->edge_length = 0;
{ } else {
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) if (node->left != NULL) {
{ for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++) {
lprofile[y + i] = MIN(lprofile[y + i], x - i); rprofile[i] = -INFINITY;
} }
} compute_rprofile(node->left, 0, 0);
compute_lprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1); hmin = node->left->height;
compute_lprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1); } 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) // This function prints the given level of the given tree, assuming
{ // that the node has the given x cordinate.
int i, notleft; void print_level(asciinode *node, int x, int level) {
if (node == NULL) int i, isleft;
return; if (node == NULL)
notleft = (node->parent_dir != -1); return;
rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2)); isleft = (node->parent_dir == -1);
if (node->right != NULL) if (level == 0) {
{ for (i = 0; i < (x - print_next - ((node->lablen - isleft) / 2)); i++) {
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) printf(" ");
{ }
rprofile[y + i] = MAX(rprofile[y + i], x + i); print_next += i;
} printf("%s", node->label);
} print_next += node->lablen;
compute_rprofile(node->left, x - node->edge_length - 1, y + node->edge_length + 1); } else if (node->edge_length >= level) {
compute_rprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1); 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 // prints ascii tree for given Node structure
//height fields of the specified tree void printTree(Node *root) {
void compute_edge_lengths(asciinode *node) asciinode *proot;
{ int xmin, i;
int h, hmin, i, delta; if (root == NULL)
if (node == NULL) return;
return; proot = build_ascii_tree(root);
compute_edge_lengths(node->left); compute_edge_lengths(proot);
compute_edge_lengths(node->right); for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) {
lprofile[i] = INFINITY;
/* first fill in the edge_length of node */ }
if (node->right == NULL && node->left == NULL) compute_lprofile(proot, 0, 0);
{ xmin = 0;
node->edge_length = 0; for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) {
} xmin = MIN(xmin, lprofile[i]);
else }
{ for (i = 0; i < proot->height; i++) {
if (node->left != NULL) print_next = 0;
{ print_level(proot, -xmin, i);
for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++) printf("\n");
{ }
rprofile[i] = -INFINITY; if (proot->height >= MAX_HEIGHT) {
} printf("(This tree is taller than %d, and may be drawn incorrectly.)\n",
compute_rprofile(node->left, 0, 0); MAX_HEIGHT);
hmin = node->left->height; }
} free_ascii_tree(proot);
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;
} }
//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);
}