#include #include #include // ----------------------------------------------------------------------- // subtree manipulation methods error phylo·addchild(bio·Node* parent, bio·Node* child) { bio·Node *it, *sibling; switch (parent->nchild) { case 1: parent->child[0]->sibling = child; case 0: parent->child[parent->nchild++] = child; break; default: sibling = parent->child[1]; for (it = parent->child[1]->sibling; it != nil; it = it->sibling) { sibling = it; } sibling->sibling = child; parent->nchild++; } child->parent = parent; return 0; } error phylo·rmchild(bio·Node* parent, bio·Node* child) { bio·Node *it, *prev; enum { error·nil, error·notfound, }; prev = nil; for (it = parent->child[0]; it != nil && it != child; it = it->sibling) { prev = it; } if (it == nil) return error·notfound; return error·nil; } // ----------------------------------------------------------------------- // subtree statistics error phylo·countnodes(bio·Node *node, int *n) { error err; bio·Node *child; *n += 1; for (child = node->child[0]; child != nil; child = child->sibling) { if (err = phylo·countnodes(child, n), err) { errorf("node count: failure at '%s'", child->name); return 1; } } return 0; } error phylo·countleafs(bio·Node *node, int *n) { error err; bio·Node *child; if (!node->nchild) { *n += 1; } for (child = node->child[0]; child != nil; child = child->sibling) { if (err = phylo·countleafs(child, n), err) { errorf("leaf count: failure at '%s'", child->name); return 1; } } return 0; } // ----------------------------------------------------------------------- // tree editing error phylo·ladderize(bio·Node *root) { int i; error err; bio·Node *child; double dists[50]; if (!root->nchild) return 0; Assert(root->nchild < arrlen(dists)); for (i = 0, child = root->child[0]; child != nil; child = child->sibling, i++) { if (err = phylo·ladderize(child), err) { errorf("ladderize: failure at '%s'", child->name); return 1; } dists[i] = child->dist; } return 0; }