week13 format mowgli AVL
This commit is contained in:
122
week13/AVL.c
122
week13/AVL.c
@@ -1,21 +1,18 @@
|
|||||||
#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;
|
||||||
|
|
||||||
@@ -28,33 +25,25 @@ int getHeight(Node *N)
|
|||||||
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)
|
Node *findNode(Node *root, int x) {
|
||||||
{
|
if (root == NULL) {
|
||||||
if (root == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root->key == x)
|
if (root->key == x) {
|
||||||
{
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x < root->key)
|
if (x < root->key) {
|
||||||
{
|
|
||||||
return findNode(root->left, x);
|
return findNode(root->left, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
return findNode(root->right, x);
|
return findNode(root->right, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *rightRotate(Node *N)
|
Node *rightRotate(Node *N) {
|
||||||
{
|
|
||||||
Node *N1 = N->left;
|
Node *N1 = N->left;
|
||||||
Node *N2 = N1->right;
|
Node *N2 = N1->right;
|
||||||
|
|
||||||
@@ -67,8 +56,7 @@ Node *rightRotate(Node *N)
|
|||||||
return N1;
|
return N1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *leftRotate(Node *N)
|
Node *leftRotate(Node *N) {
|
||||||
{
|
|
||||||
Node *N1 = N->right;
|
Node *N1 = N->right;
|
||||||
Node *N2 = N1->left;
|
Node *N2 = N1->left;
|
||||||
|
|
||||||
@@ -81,22 +69,18 @@ Node *leftRotate(Node *N)
|
|||||||
return N1;
|
return N1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *minNode(Node *N)
|
Node *minNode(Node *N) {
|
||||||
{
|
while (N->left != NULL) {
|
||||||
while (N->left != NULL)
|
|
||||||
{
|
|
||||||
N = N->left;
|
N = N->left;
|
||||||
}
|
}
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *insertNode(Node **root, int x)
|
Node *insertNode(Node **root, int x) {
|
||||||
{
|
|
||||||
Node *ans;
|
Node *ans;
|
||||||
|
|
||||||
/* insert the data */
|
/* insert the data */
|
||||||
if (*root == NULL)
|
if (*root == NULL) {
|
||||||
{
|
|
||||||
Node *temp = (Node *)malloc(sizeof(Node));
|
Node *temp = (Node *)malloc(sizeof(Node));
|
||||||
temp->key = x;
|
temp->key = x;
|
||||||
temp->height = 0;
|
temp->height = 0;
|
||||||
@@ -105,93 +89,75 @@ Node *insertNode(Node **root, int x)
|
|||||||
*root = temp;
|
*root = temp;
|
||||||
ans = temp;
|
ans = temp;
|
||||||
return ans;
|
return ans;
|
||||||
}
|
} else if ((*root)->key > x) {
|
||||||
else if ((*root)->key > x)
|
|
||||||
{
|
|
||||||
ans = insertNode(&(*root)->left, x);
|
ans = insertNode(&(*root)->left, x);
|
||||||
}
|
} else if ((*root)->key < x) {
|
||||||
else if ((*root)->key < x)
|
|
||||||
{
|
|
||||||
ans = insertNode(&(*root)->right, x);
|
ans = insertNode(&(*root)->right, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the unbalance problem */
|
/* handle the unbalance problem */
|
||||||
(*root)->height = 1 + max(getHeight((*root)->left), getHeight((*root)->right));
|
(*root)->height =
|
||||||
|
1 + max(getHeight((*root)->left), getHeight((*root)->right));
|
||||||
|
|
||||||
int balance = getBalance(*root);
|
int balance = getBalance(*root);
|
||||||
|
|
||||||
/* case 1 left left unbalance */
|
/* case 1 left left unbalance */
|
||||||
if (balance > 1 && getBalance((*root)->left) >= 0)
|
if (balance > 1 && getBalance((*root)->left) >= 0) {
|
||||||
{
|
|
||||||
*root = rightRotate(*root);
|
*root = rightRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 2 left right unbalance */
|
/* case 2 left right unbalance */
|
||||||
if (balance > 1 && getBalance((*root)->left) < 0)
|
if (balance > 1 && getBalance((*root)->left) < 0) {
|
||||||
{
|
|
||||||
(*root)->left = leftRotate((*root)->left);
|
(*root)->left = leftRotate((*root)->left);
|
||||||
*root = rightRotate(*root);
|
*root = rightRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 3 right left unbalance */
|
/* case 3 right left unbalance */
|
||||||
if (balance < -1 && getBalance((*root)->right) > 0)
|
if (balance < -1 && getBalance((*root)->right) > 0) {
|
||||||
{
|
|
||||||
(*root)->right = rightRotate((*root)->right);
|
(*root)->right = rightRotate((*root)->right);
|
||||||
*root = leftRotate(*root);
|
*root = leftRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 4 right right unbalance */
|
/* case 4 right right unbalance */
|
||||||
if (balance < -1 && getBalance((*root)->right) <= 0)
|
if (balance < -1 && getBalance((*root)->right) <= 0) {
|
||||||
{
|
|
||||||
*root = leftRotate(*root);
|
*root = leftRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *deleteNode(Node **root, int x)
|
Node *deleteNode(Node **root, int x) {
|
||||||
{
|
|
||||||
Node *temp = *root;
|
Node *temp = *root;
|
||||||
|
|
||||||
if (*root == NULL)
|
if (*root == NULL)
|
||||||
return *root;
|
return *root;
|
||||||
|
|
||||||
if (x < (*root)->key)
|
if (x < (*root)->key) {
|
||||||
{
|
|
||||||
temp = deleteNode(&(*root)->left, x);
|
temp = deleteNode(&(*root)->left, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (x > (*root)->key)
|
else if (x > (*root)->key) {
|
||||||
{
|
|
||||||
temp = deleteNode(&(*root)->right, x);
|
temp = deleteNode(&(*root)->right, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
if ((*root)->left == NULL || (*root)->right == NULL) {
|
||||||
if ((*root)->left == NULL || (*root)->right == NULL)
|
|
||||||
{
|
|
||||||
Node *child = (*root)->left != NULL ? (*root)->left : (*root)->right;
|
Node *child = (*root)->left != NULL ? (*root)->left : (*root)->right;
|
||||||
|
|
||||||
if (child == NULL)
|
if (child == NULL) { // no child case;
|
||||||
{ // no child case;
|
|
||||||
*root = NULL;
|
*root = NULL;
|
||||||
return temp;
|
return temp;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
(*root)->key = child->key;
|
(*root)->key = child->key;
|
||||||
if ((*root)->left && (*root)->left->key == child->key)
|
if ((*root)->left &&
|
||||||
{ // left child case;
|
(*root)->left->key == child->key) { // left child case;
|
||||||
temp = deleteNode(&(*root)->left, child->key);
|
temp = deleteNode(&(*root)->left, child->key);
|
||||||
}
|
} else if ((*root)->right &&
|
||||||
else if ((*root)->right && (*root)->right->key == child->key)
|
(*root)->right->key == child->key) { // right child case;
|
||||||
{ // right child case;
|
|
||||||
temp = deleteNode(&(*root)->right, child->key);
|
temp = deleteNode(&(*root)->right, child->key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else { // two children case;
|
||||||
else
|
|
||||||
{ // two children case;
|
|
||||||
Node *child = minNode((*root)->right);
|
Node *child = minNode((*root)->right);
|
||||||
(*root)->key = child->key;
|
(*root)->key = child->key;
|
||||||
temp = deleteNode(&(*root)->right, child->key);
|
temp = deleteNode(&(*root)->right, child->key);
|
||||||
@@ -203,39 +169,35 @@ Node *deleteNode(Node **root, int x)
|
|||||||
|
|
||||||
int balance = getBalance(*root);
|
int balance = getBalance(*root);
|
||||||
|
|
||||||
(*root)->height = 1 + max(getHeight((*root)->left), getHeight((*root)->right));
|
(*root)->height =
|
||||||
|
1 + max(getHeight((*root)->left), getHeight((*root)->right));
|
||||||
|
|
||||||
/* case 1 left left unbalance */
|
/* case 1 left left unbalance */
|
||||||
if (balance > 1 && getBalance((*root)->left) >= 0)
|
if (balance > 1 && getBalance((*root)->left) >= 0) {
|
||||||
{
|
|
||||||
*root = rightRotate(*root);
|
*root = rightRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 2 left right unbalance */
|
/* case 2 left right unbalance */
|
||||||
if (balance > 1 && getBalance((*root)->left) < 0)
|
if (balance > 1 && getBalance((*root)->left) < 0) {
|
||||||
{
|
|
||||||
(*root)->left = leftRotate((*root)->left);
|
(*root)->left = leftRotate((*root)->left);
|
||||||
*root = rightRotate(*root);
|
*root = rightRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 3 right left unbalance */
|
/* case 3 right left unbalance */
|
||||||
if (balance < -1 && getBalance((*root)->right) > 0)
|
if (balance < -1 && getBalance((*root)->right) > 0) {
|
||||||
{
|
|
||||||
(*root)->right = rightRotate((*root)->right);
|
(*root)->right = rightRotate((*root)->right);
|
||||||
*root = leftRotate(*root);
|
*root = leftRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* case 4 right right unbalance */
|
/* case 4 right right unbalance */
|
||||||
if (balance < -1 && getBalance((*root)->right) <= 0)
|
if (balance < -1 && getBalance((*root)->right) <= 0) {
|
||||||
{
|
|
||||||
*root = leftRotate(*root);
|
*root = leftRotate(*root);
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyTree(Node *root)
|
void destroyTree(Node *root) {
|
||||||
{
|
|
||||||
if (root == NULL)
|
if (root == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
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;
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
|
#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,
|
||||||
|
15, 19, 23, 31, 1, 6, 9, 13, 22, 7};
|
||||||
int len = 20, x;
|
int len = 20, x;
|
||||||
for (int i = 0; i < len; i++)
|
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
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
|
#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
|
||||||
@@ -37,18 +36,11 @@ int gap = 3;
|
|||||||
// 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)
|
int MAX(int X, int Y) { return ((X) > (Y)) ? (X) : (Y); }
|
||||||
{
|
|
||||||
return ((X) > (Y)) ? (X) : (Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
asciinode *build_ascii_tree_recursive(Node *t)
|
asciinode *build_ascii_tree_recursive(Node *t) {
|
||||||
{
|
|
||||||
asciinode *node;
|
asciinode *node;
|
||||||
|
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
@@ -58,13 +50,11 @@ asciinode *build_ascii_tree_recursive(Node *t)
|
|||||||
node->left = build_ascii_tree_recursive(t->left);
|
node->left = build_ascii_tree_recursive(t->left);
|
||||||
node->right = build_ascii_tree_recursive(t->right);
|
node->right = build_ascii_tree_recursive(t->right);
|
||||||
|
|
||||||
if (node->left != NULL)
|
if (node->left != NULL) {
|
||||||
{
|
|
||||||
node->left->parent_dir = -1;
|
node->left->parent_dir = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->right != NULL)
|
if (node->right != NULL) {
|
||||||
{
|
|
||||||
node->right->parent_dir = 1;
|
node->right->parent_dir = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +66,7 @@ asciinode *build_ascii_tree_recursive(Node *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy the tree into the ascii node structre
|
// Copy the tree into the ascii node structre
|
||||||
asciinode *build_ascii_tree(Node *t)
|
asciinode *build_ascii_tree(Node *t) {
|
||||||
{
|
|
||||||
asciinode *node;
|
asciinode *node;
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -87,8 +76,7 @@ asciinode *build_ascii_tree(Node *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Free all the nodes of the given tree
|
// Free all the nodes of the given tree
|
||||||
void free_ascii_tree(asciinode *node)
|
void free_ascii_tree(asciinode *node) {
|
||||||
{
|
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return;
|
return;
|
||||||
free_ascii_tree(node->left);
|
free_ascii_tree(node->left);
|
||||||
@@ -100,46 +88,43 @@ void free_ascii_tree(asciinode *node)
|
|||||||
// It assumes that the center of the label of the root of this 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
|
// is located at a position (x,y). It assumes that the edge_length
|
||||||
// fields have been computed for this tree.
|
// fields have been computed for this tree.
|
||||||
void compute_lprofile(asciinode *node, int x, int y)
|
void compute_lprofile(asciinode *node, int x, int y) {
|
||||||
{
|
|
||||||
int i, isleft;
|
int i, isleft;
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return;
|
return;
|
||||||
isleft = (node->parent_dir == -1);
|
isleft = (node->parent_dir == -1);
|
||||||
lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2));
|
lprofile[y] = MIN(lprofile[y], x - ((node->lablen - isleft) / 2));
|
||||||
if (node->left != NULL)
|
if (node->left != NULL) {
|
||||||
{
|
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) {
|
||||||
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++)
|
|
||||||
{
|
|
||||||
lprofile[y + i] = MIN(lprofile[y + i], x - 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->left, x - node->edge_length - 1,
|
||||||
compute_lprofile(node->right, x + node->edge_length + 1, y + node->edge_length + 1);
|
y + node->edge_length + 1);
|
||||||
|
compute_lprofile(node->right, x + node->edge_length + 1,
|
||||||
|
y + node->edge_length + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute_rprofile(asciinode *node, int x, int y)
|
void compute_rprofile(asciinode *node, int x, int y) {
|
||||||
{
|
|
||||||
int i, notleft;
|
int i, notleft;
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return;
|
return;
|
||||||
notleft = (node->parent_dir != -1);
|
notleft = (node->parent_dir != -1);
|
||||||
rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2));
|
rprofile[y] = MAX(rprofile[y], x + ((node->lablen - notleft) / 2));
|
||||||
if (node->right != NULL)
|
if (node->right != NULL) {
|
||||||
{
|
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++) {
|
||||||
for (i = 1; i <= node->edge_length && y + i < MAX_HEIGHT; i++)
|
|
||||||
{
|
|
||||||
rprofile[y + i] = MAX(rprofile[y + i], x + 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->left, x - node->edge_length - 1,
|
||||||
compute_rprofile(node->right, x + node->edge_length + 1, y + 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 fills in the edge_length and
|
// This function fills in the edge_length and
|
||||||
// height fields of the specified tree
|
// height fields of the specified tree
|
||||||
void compute_edge_lengths(asciinode *node)
|
void compute_edge_lengths(asciinode *node) {
|
||||||
{
|
|
||||||
int h, hmin, i, delta;
|
int h, hmin, i, delta;
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -147,41 +132,29 @@ void compute_edge_lengths(asciinode *node)
|
|||||||
compute_edge_lengths(node->right);
|
compute_edge_lengths(node->right);
|
||||||
|
|
||||||
/* first fill in the edge_length of node */
|
/* first fill in the edge_length of node */
|
||||||
if (node->right == NULL && node->left == NULL)
|
if (node->right == NULL && node->left == NULL) {
|
||||||
{
|
|
||||||
node->edge_length = 0;
|
node->edge_length = 0;
|
||||||
}
|
} else {
|
||||||
else
|
if (node->left != NULL) {
|
||||||
{
|
for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++) {
|
||||||
if (node->left != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < node->left->height && i < MAX_HEIGHT; i++)
|
|
||||||
{
|
|
||||||
rprofile[i] = -INFINITY;
|
rprofile[i] = -INFINITY;
|
||||||
}
|
}
|
||||||
compute_rprofile(node->left, 0, 0);
|
compute_rprofile(node->left, 0, 0);
|
||||||
hmin = node->left->height;
|
hmin = node->left->height;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hmin = 0;
|
hmin = 0;
|
||||||
}
|
}
|
||||||
if (node->right != NULL)
|
if (node->right != NULL) {
|
||||||
{
|
for (i = 0; i < node->right->height && i < MAX_HEIGHT; i++) {
|
||||||
for (i = 0; i < node->right->height && i < MAX_HEIGHT; i++)
|
|
||||||
{
|
|
||||||
lprofile[i] = INFINITY;
|
lprofile[i] = INFINITY;
|
||||||
}
|
}
|
||||||
compute_lprofile(node->right, 0, 0);
|
compute_lprofile(node->right, 0, 0);
|
||||||
hmin = MIN(node->right->height, hmin);
|
hmin = MIN(node->right->height, hmin);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hmin = 0;
|
hmin = 0;
|
||||||
}
|
}
|
||||||
delta = 4;
|
delta = 4;
|
||||||
for (i = 0; i < hmin; i++)
|
for (i = 0; i < hmin; i++) {
|
||||||
{
|
|
||||||
delta = MAX(delta, gap + 1 + rprofile[i] - lprofile[i]);
|
delta = MAX(delta, gap + 1 + rprofile[i] - lprofile[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,8 +162,7 @@ void compute_edge_lengths(asciinode *node)
|
|||||||
// two leaves to be within 1, instead of 2
|
// two leaves to be within 1, instead of 2
|
||||||
if (((node->left != NULL && node->left->height == 1) ||
|
if (((node->left != NULL && node->left->height == 1) ||
|
||||||
(node->right != NULL && node->right->height == 1)) &&
|
(node->right != NULL && node->right->height == 1)) &&
|
||||||
delta > 4)
|
delta > 4) {
|
||||||
{
|
|
||||||
delta--;
|
delta--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,12 +171,10 @@ void compute_edge_lengths(asciinode *node)
|
|||||||
|
|
||||||
// now fill in the height of node
|
// now fill in the height of node
|
||||||
h = 1;
|
h = 1;
|
||||||
if (node->left != NULL)
|
if (node->left != NULL) {
|
||||||
{
|
|
||||||
h = MAX(node->left->height + node->edge_length + 1, h);
|
h = MAX(node->left->height + node->edge_length + 1, h);
|
||||||
}
|
}
|
||||||
if (node->right != NULL)
|
if (node->right != NULL) {
|
||||||
{
|
|
||||||
h = MAX(node->right->height + node->edge_length + 1, h);
|
h = MAX(node->right->height + node->edge_length + 1, h);
|
||||||
}
|
}
|
||||||
node->height = h;
|
node->height = h;
|
||||||
@@ -212,84 +182,67 @@ void compute_edge_lengths(asciinode *node)
|
|||||||
|
|
||||||
// This function prints the given level of the given tree, assuming
|
// This function prints the given level of the given tree, assuming
|
||||||
// that the node has the given x cordinate.
|
// that the node has the given x cordinate.
|
||||||
void print_level(asciinode *node, int x, int level)
|
void print_level(asciinode *node, int x, int level) {
|
||||||
{
|
|
||||||
int i, isleft;
|
int i, isleft;
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return;
|
return;
|
||||||
isleft = (node->parent_dir == -1);
|
isleft = (node->parent_dir == -1);
|
||||||
if (level == 0)
|
if (level == 0) {
|
||||||
{
|
for (i = 0; i < (x - print_next - ((node->lablen - isleft) / 2)); i++) {
|
||||||
for (i = 0; i < (x - print_next - ((node->lablen - isleft) / 2)); i++)
|
|
||||||
{
|
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
print_next += i;
|
print_next += i;
|
||||||
printf("%s", node->label);
|
printf("%s", node->label);
|
||||||
print_next += node->lablen;
|
print_next += node->lablen;
|
||||||
}
|
} else if (node->edge_length >= level) {
|
||||||
else if (node->edge_length >= level)
|
if (node->left != NULL) {
|
||||||
{
|
for (i = 0; i < (x - print_next - (level)); i++) {
|
||||||
if (node->left != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < (x - print_next - (level)); i++)
|
|
||||||
{
|
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
print_next += i;
|
print_next += i;
|
||||||
printf("/");
|
printf("/");
|
||||||
print_next++;
|
print_next++;
|
||||||
}
|
}
|
||||||
if (node->right != NULL)
|
if (node->right != NULL) {
|
||||||
{
|
for (i = 0; i < (x - print_next + (level)); i++) {
|
||||||
for (i = 0; i < (x - print_next + (level)); i++)
|
|
||||||
{
|
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
print_next += i;
|
print_next += i;
|
||||||
printf("\\");
|
printf("\\");
|
||||||
print_next++;
|
print_next++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
print_level(node->left, x - node->edge_length - 1,
|
||||||
{
|
|
||||||
print_level(node->left,
|
|
||||||
x - node->edge_length - 1,
|
|
||||||
level - node->edge_length - 1);
|
level - node->edge_length - 1);
|
||||||
print_level(node->right,
|
print_level(node->right, x + node->edge_length + 1,
|
||||||
x + node->edge_length + 1,
|
|
||||||
level - node->edge_length - 1);
|
level - node->edge_length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints ascii tree for given Node structure
|
// prints ascii tree for given Node structure
|
||||||
void printTree(Node *root)
|
void printTree(Node *root) {
|
||||||
{
|
|
||||||
asciinode *proot;
|
asciinode *proot;
|
||||||
int xmin, i;
|
int xmin, i;
|
||||||
if (root == NULL)
|
if (root == NULL)
|
||||||
return;
|
return;
|
||||||
proot = build_ascii_tree(root);
|
proot = build_ascii_tree(root);
|
||||||
compute_edge_lengths(proot);
|
compute_edge_lengths(proot);
|
||||||
for (i = 0; i < proot->height && i < MAX_HEIGHT; i++)
|
for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) {
|
||||||
{
|
|
||||||
lprofile[i] = INFINITY;
|
lprofile[i] = INFINITY;
|
||||||
}
|
}
|
||||||
compute_lprofile(proot, 0, 0);
|
compute_lprofile(proot, 0, 0);
|
||||||
xmin = 0;
|
xmin = 0;
|
||||||
for (i = 0; i < proot->height && i < MAX_HEIGHT; i++)
|
for (i = 0; i < proot->height && i < MAX_HEIGHT; i++) {
|
||||||
{
|
|
||||||
xmin = MIN(xmin, lprofile[i]);
|
xmin = MIN(xmin, lprofile[i]);
|
||||||
}
|
}
|
||||||
for (i = 0; i < proot->height; i++)
|
for (i = 0; i < proot->height; i++) {
|
||||||
{
|
|
||||||
print_next = 0;
|
print_next = 0;
|
||||||
print_level(proot, -xmin, i);
|
print_level(proot, -xmin, i);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
if (proot->height >= MAX_HEIGHT)
|
if (proot->height >= MAX_HEIGHT) {
|
||||||
{
|
printf("(This tree is taller than %d, and may be drawn incorrectly.)\n",
|
||||||
printf("(This tree is taller than %d, and may be drawn incorrectly.)\n", MAX_HEIGHT);
|
MAX_HEIGHT);
|
||||||
}
|
}
|
||||||
free_ascii_tree(proot);
|
free_ascii_tree(proot);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user