📄 gatreebase.cpp
字号:
if(bchild){ bchild->parent = a; for(GANodeBASE * n=bchild->next; n && n != bchild; n=n->next) n->parent = a; } if(anext == b && bnext != a){ // same as b->prev = a a->prev = b; a->next = bnext; b->prev = aprev; b->next = a; aprev->next = b; bnext->prev = a; } else if(bnext == a && anext != b){ // same as a->prev = b a->prev = bprev; a->next = b; b->prev = a; b->next = anext; anext->prev = b; bprev->next = a; } } else{ // a & b are not adjacent if(bprev == b || bnext == b){ a->prev = a; a->next = a; } else{ a->prev = bprev; a->next = bnext; bprev->next = a; bnext->prev = a; } if(aprev == a || anext == a){ b->prev = b; b->next = b; } else{ b->prev = aprev; b->next = anext; aprev->next = b; anext->prev = b; } if(achild == b){ // same as b->parent = a a->parent = b; a->child = bchild; b->parent = aparent; b->child = a; if(aparent && aparent->child == a) aparent->child = b; for(GANodeBASE * n=a->next; n && n != a; n=n->next) n->parent = b; if(bchild){ bchild->parent = a; for(GANodeBASE * n=bchild->next; n && n != bchild; n=n->next) n->parent = a; } } else if(bchild == a){ // same as a->parent = b a->parent = bparent; a->child = b; b->parent = a; b->child = achild; if(bparent && bparent->child == b) bparent->child = a; if(achild){ achild->parent = b; for(GANodeBASE * n=achild->next; n && n != achild; n=n->next) n->parent = b; } for(GANodeBASE * n=b->next; n && n != b; n=n->next) n->parent = a; } else{ // a and b are not adjacent nor parent-child a->parent = bparent; a->child = bchild; b->parent = aparent; b->child = achild; if(aparent == bparent){ if(aparent && aparent->child == a) aparent->child = b; else if(bparent && bparent->child == b) bparent->child = a; } else{ if(aparent && aparent->child == a) aparent->child = b; if(bparent && bparent->child == b) bparent->child = a; } if(achild){ achild->parent = b; for(GANodeBASE * n=achild->next; n && n != achild; n=n->next) n->parent = b; } if(bchild){ bchild->parent = a; for(GANodeBASE * n=bchild->next; n && n != bchild; n=n->next) n->parent = a; } } } if(rt == a) rt = b; // this only works if they're in the same tree! else if(rt == b) rt = a; return NO_ERR;}// Return the number of nodes in the tree. We do a complete traversal of the// tree and count the number of nodes that we encounter. Could do this breadth// first or depth first - doesn't really matter. We have to traverse the // entire tree to do the count.// We have to do a little work-around here to get through the const-ness of// the size method. Its ok to call size on a const object because it does not// modify the logical state of the object. It does, however, modify the// physical state of the object. So to work around the strictness of the // const specifier, we do a little pointer magic and cast this to be non-const.intGATreeBASE::size() const{ if(!csz) return sz; GATreeBASE * This = CON_CAST(GATreeBASE *, this); This->csz = 0; return(This->sz = _GATreeSize(rt));}// Return the number of levels in the tree. We do a complete traversal of the// tree and keep a count of the number of times we go down and come up a level.// I should be able to combine _size and _depth so we don't have to do two// traversals...intGATreeBASE::depth() const{ if(!cdpth) return dpth; GATreeBASE * This = CON_CAST(GATreeBASE *, this); This->cdpth = 0; return(This->dpth = _GATreeDepth(rt));}// Is node i an ancestor of node j or vice versa? If so, we return 1. Other-// wise we return a 0.int GATreeBASE::ancestral(unsigned int i, unsigned int j) const { GATreeIterBASE aiter(*this); GATreeIterBASE biter(*this); GANodeBASE * aparent, *a; GANodeBASE * bparent, *b; aparent = a = aiter.warp(i); bparent = b = biter.warp(j); while(aparent && aparent != b) aparent = aparent->parent; if(aparent == b) return 1; while(bparent && bparent != a) bparent = bparent->parent; if(bparent == a) return 1; return 0;}/* ----------------------------------------------------------------------------Recursive routines for the TreeBASE objects---------------------------------------------------------------------------- */static int_GATreeSize(GANodeBASE * node){ if(!node) return 0; int count = 1 + _GATreeSize(node->child); for(GANodeBASE * tmp=node->next; tmp && tmp != node; tmp=tmp->next){ count++; count += _GATreeSize(tmp->child); } return count;}static int_GATreeDepth(GANodeBASE * node){ if(!node) return 0; int depth; int maxdepth = 1 + _GATreeDepth(node->child); for(GANodeBASE * tmp=node->next; tmp != node; tmp=tmp->next){ depth = 1 + _GATreeDepth(tmp->child); maxdepth = maxdepth > depth ? maxdepth : depth; } return maxdepth;}/* ----------------------------------------------------------------------------TreeIterBASE---------------------------------------------------------------------------- */// Return the root of the specified node.GANodeBASE * GATreeIterBASE::root(GANodeBASE * c){ if(!c) return (GANodeBASE *)0; while(c->parent != (GANodeBASE *)0) c = c->parent; return(node = c);}// Return the eldest child in a row of siblings. The eldest is the one that // the parent of that row points to.// This could get into an infinite loop if the tree structure were ever // corrupted, so be sure that it doesn't! Also, it will break if the parent// member is not set in any child, so be sure that never happens either.// Remember to set the current node to the one we found.GANodeBASE * GATreeIterBASE::eldest(GANodeBASE * c){ if(!c) return (GANodeBASE *)0; if(!c->parent) return(node=c); GANodeBASE * tmp = c; while(tmp->parent->child != tmp) tmp = tmp->next; return(node = tmp);}// Return the youngest child in a row of siblings. The youngest is the last// one in the row (ie the prev for the eldest since we're using circular lists)// Basically we just find the eldest then take the one previous to that one.// Remember to set the current node to the one we found.GANodeBASE * GATreeIterBASE::youngest(GANodeBASE * c){ if(!c) return (GANodeBASE *)0; if(!c->parent) return(node=c); GANodeBASE * tmp = c; while(tmp->parent->child != tmp) tmp = tmp->next; return(node = tmp->prev);}// Return the number of siblings for the specified node. Notice that this // function returns the number of siblings INCLUDING the specified node.intGATreeIterBASE::nsiblings(GANodeBASE * c){ GANodeBASE * tmp = c; int n=1; while(tmp->next && ((tmp=tmp->next) != c)) n++; return n;}// Return the number of children for the specified node. This is basically the// same code as the nsiblings routine, but we look at the child of the node, // not the node itself.intGATreeIterBASE::nchildren(GANodeBASE * c){ if(!c->child) return 0; GANodeBASE * tmp = c->child; int n=1; while(tmp->next && ((tmp=tmp->next) != c->child)) n++; return n;}// Set the current node to the node indexed by the integer x. If x is out of// bounds, we return NULL and don't change the state of the iterator. This // method uses a depth-first traversal to find the node. Root node is 0, then// we go up from there.GANodeBASE *GATreeIterBASE::warp(unsigned int x){ unsigned int w=0; GANodeBASE * tmp = _GATreeTraverse(x, w, root()); if(tmp) node = tmp; return(tmp);}// Return the number of nodes in the tree from the specified node on down. // Similar to the TreeBASE size method, but we don't set the sz member and // we can't cache the size since this could be called on any node.intGATreeIterBASE::size(GANodeBASE * n){ return(_GATreeSize(n));}// Return the depth of the tree from the specified node on down.intGATreeIterBASE::depth(GANodeBASE * n){ return(_GATreeDepth(n));}// Traverse the tree (depth-first) until we come to the node with the index// specified by 'index'. Return NULL if cur != index.GANodeBASE *_GATreeTraverse(unsigned int index, unsigned int & cur, GANodeBASE * node){ if(!node) return (GANodeBASE *)0; if(cur == index) return node; cur++; GANodeBASE * n; if((n = _GATreeTraverse(index, cur, node->child)) != (GANodeBASE *)0) return n; for(GANodeBASE * tmp=node->next; tmp && tmp != node; tmp=tmp->next){ if(cur == index) return tmp; cur++; if((n = _GATreeTraverse(index, cur, tmp->child)) != (GANodeBASE *)0) return n; } return (GANodeBASE *)0;}// Comparison operators for a a tree check for identical tree structure// only (no check for same contents of nodes). These check for// similar tree structure - we traverse one tree and expect the second to be// just like it (depth-first traversal). If there is any difference along the// way, then we return a not equal.// Neither of these operators affects the internal iterator of either// tree genome in any way.// Recursively traverse two trees at the same time. Return 1 if they are // different, return a 0 if they are identical. This checks only the tree// structure, not the node contents.int_GATreeCompare(GANodeBASE * anode, GANodeBASE * bnode){ if(anode==0 && bnode==0) return 0; if(anode==0 || bnode==0) return 1; int count = _GATreeCompare(anode->child, bnode->child); for(GANodeBASE * atmp=anode->next, * btmp=bnode->next; atmp && atmp != anode; atmp=atmp->next, btmp=btmp->next){ count += _GATreeCompare(atmp->child, btmp->child); } return count;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -