//------------------------------------------------------------------------------ void Tree::fillInAncestors (NodePtr p) { NodePtr q = p->GetAnc (); NodePtr r = p; while (q != Root) { if ( (q->GetSibling () && !(r->IsTheChild ())) || (!(q->IsTheChild ()) && r->IsTheChild()) ) { if (r ==p && q->GetHeight() == q->GetAnc()->GetHeight()) Line[q->GetAnc()->GetHeight()] = SIB; else Line[q->GetAnc()->GetHeight()] = VBAR; } r = q; q = q->GetAnc (); } }
//------------------------------------------------------------------------------ void Tree::drawInteriorEdge (NodePtr p) { NodePtr r = p->GetAnc (); int stop = r->GetHeight(); if (p->IsTheChild ()) { // Visiting ancestor for the first time, so draw the // end symbol if (r == Root) { // if (IsRooted ()) Line[stop] = TEE; // « // else // Line[stop] = VBAR; // Ò } else { Line[stop] = TEE; // « } // Draw branch itself if (r != Root) { // Line int start = r->GetAnc()->GetHeight(); for (int i = start + 1; i < stop; i++) { Line[i] = HBAR; // € } // Start symbol if (start == stop) Line[start] = VBAR; // Ò else if (r->IsTheChild ()) Line[start] = LEFT; // ò else if (r->GetSibling ()) Line[start] = SIB; // Ì else Line[start] = RIGHT; // Ë // fillInAncestors (r); } } else { // Just draw nodes below Line[stop] = VBAR; fillInAncestors (p->GetSibling()); } // Output the line Line[stop + 1] = '\0'; drawLine (r, p->IsTheChild()); /* *treeStream << Line.c_str(); // *treeStream << "h=" << r->GetHeight() << " w= " // << r->GetWeight() << "-- "; // Draw internal label, if present string s = r->GetLabel(); if (s != "" && p->IsTheChild ()) *treeStream << r->GetLabel(); *treeStream << endl; */ // Clear the line for the next pass for (int i = 0; i < (Leaves + 2); i++) // to do: get a better limit Line[i] = ' '; }
NodePtr Tree::RemoveNode (NodePtr Node) { NodePtr result = NULL; if (Node == Root) { if (Leaves == 1) { Root = NULL; Node->SetAnc (NULL); Leaves = Internals = 0; } return result; } NodePtr p; NodePtr Ancestor = Node->GetAnc(); if (Ancestor->GetDegree() == 2) { // ancestor is binary, so remove node and its ancestor if (Node->IsTheChild ()) p = Node->GetSibling(); else p = Ancestor->GetChild(); NodePtr q = Ancestor->GetAnc(); p->SetAnc (q); if (q != NULL) { if (Ancestor->IsTheChild()) q->SetChild (p); else { NodePtr r = Ancestor->LeftSiblingOf (); r->SetSibling (p); } p->SetSibling (Ancestor->GetSibling()); result = p; } else { // Ancestor is the root Root = p; p->SetSibling (NULL); result = p; } delete Ancestor; Internals--; if (Node->IsLeaf()) Leaves--; Node->SetAnc (NULL); Node->SetSibling (NULL); } else { // polytomy, just remove node NodePtr q; if (Node->IsTheChild()) { Ancestor->SetChild (Node->GetSibling()); q = Node->GetSibling (); } else { q = Node->LeftSiblingOf (); q->SetSibling (Node->GetSibling ()); } Node->SetSibling (NULL); Node->SetAnc (NULL); if (Node->IsLeaf()) Leaves--; Ancestor->SetDegree (Ancestor->GetDegree() - 1); result = q; } }