/* * This function fills in the edge_length and height fields of the * specified tree. */ void compute_edge_lengths(Pnode * pn) { int h, hmin, i, delta; if (pn == NULL) return; compute_edge_lengths(pn->left); compute_edge_lengths(pn->right); /* first fill in the edge_length of pn */ if (pn->right == NULL && pn->left == NULL) { pn->edge_length = 0; } else { if (pn->left != NULL) { for (i = 0; i < pn->left->height && i < MAX_HEIGHT; i++) { rprofile[i] = -INFINITY; } compute_rprofile(pn->left, 0, 0); hmin = pn->left->height; } else { hmin = 0; } if (pn->right != NULL) { for (i = 0; i < pn->right->height && i < MAX_HEIGHT; i++) { lprofile[i] = INFINITY; } compute_lprofile(pn->right, 0, 0); hmin = min(pn->right->height, hmin); } else { hmin = 0; } delta = 4; for (i = 0; i < hmin; i++) { delta = max(delta, 2 + 1 + rprofile[i] - lprofile[i]); /* the "2" guarantees a gap of 2 between different parts of the tree */ } /* If the node has two children of height 1, then we allow the two leaves to be within 1, instead of 2 */ if (((pn->left != NULL && pn->left->height == 1) || (pn->right != NULL && pn->right->height == 1)) && delta > 4) delta--; pn->edge_length = ((delta + 1) / 2) - 1; } /* now fill in the height of pn */ h = 1; if (pn->left != NULL) { h = max(pn->left->height + pn->edge_length + 1, h); } if (pn->right != NULL) { h = max(pn->right->height + pn->edge_length + 1, h); } pn->height = h; }
//--------------------------------------------------------- //This function fills in the edge_length and //height fields of the specified tree void AsciiTree::compute_edge_lengths(AsciiNode* ascii_node) { if(ascii_node==NULL) return; int h, hmin, delta; compute_edge_lengths(ascii_node->left); compute_edge_lengths(ascii_node->right); // first fill in the edge_length of node if(ascii_node->right==NULL && ascii_node->left==NULL) ascii_node->edge_length=0; else { if(ascii_node->left!=NULL) { for(int i=0; i<ascii_node->left->height && i<MAX_HEIGHT; ++i) rprofile[i]=-INFINITY; compute_rprofile(ascii_node->left, 0, 0); hmin=ascii_node->left->height; } else hmin=0; if(ascii_node->right!=NULL) { for(int i=0; i<ascii_node->right->height && i<MAX_HEIGHT; ++i) lprofile[i]=INFINITY; compute_lprofile(ascii_node->right, 0, 0); hmin=std::min(ascii_node->right->height, hmin); } else hmin=0; delta=4; for(int i=0; i<hmin; ++i) delta=std::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(((ascii_node->left!=NULL && ascii_node->left->height==1) || (ascii_node->right!=NULL && ascii_node->right->height==1)) && delta>4) --delta; ascii_node->edge_length=((delta+1)/2)-1; } //now fill in the height of node h=1; if(ascii_node->left!=NULL) h=std::max(ascii_node->left->height+ascii_node->edge_length+1, h); if(ascii_node->right!=NULL) h=std::max(ascii_node->right->height+ascii_node->edge_length+1, h); ascii_node->height=h; }
/* * This pretty-prints the given tree, left-justified. * The tree is drawn in such a way that both of the edges down from * a node are the same length. This length is the minimum such that * the two subtrees are separated by at least two blanks. */ void tree_draw(const T t) { Pnode *proot; int xmin, i; if (t == NULL) return; proot = build_ptree(t->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_ptree(proot); }
//--------------------------------------------------------- //prints ascii tree for given Node structure void AsciiTree::print_ascii_tree() { if(_node==NULL) return; AsciiNode* ascii_root=build_ascii_tree(_node); compute_edge_lengths(ascii_root); for(int i=0; i<ascii_root->height && i<MAX_HEIGHT; ++i) lprofile[i]=INFINITY; compute_lprofile(ascii_root, 0, 0); int xmin=0; for(int i=0; i<ascii_root->height && i<MAX_HEIGHT; ++i) xmin=std::min(xmin, lprofile[i]); for(int i=0; i<ascii_root->height; ++i) { print_next=0; print_level(ascii_root, -xmin, i); std::cout<<std::endl; } if(ascii_root->height>=MAX_HEIGHT) std::cout<<"(This tree is taller than "<<MAX_HEIGHT<<", and may be drawn incorrectly.)"<<std::endl; free_ascii_tree(ascii_root); }
//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; }