private TreeEvalItem <TTreeNode> ProcessNextEvaluationsForRBFS(TTreeNode target, TreeNodePath path, int targetDepth) { if (target == null) { return(null); } var parent = m_traversalParameters.GetParentMethod(target); if (parent == null) { return(null); } TTreeNode nextClosestSibling = null; int nextClosestSiblingIndex = -1; int childIndex = 0; foreach (var sibling in m_traversalParameters.GetChildrenMethod(parent)) { if (sibling == target) { break; } nextClosestSiblingIndex = childIndex++; nextClosestSibling = sibling; } // No siblings, recurse to the parent/grandparent if (nextClosestSibling == null) { TreeEvalItem <TTreeNode> cousin = this.GetNextRBFSCousin(parent, path.CopyAndRemoveEnd(), targetDepth); if (cousin != null) { return(cousin); } // Looks like end of this depth... time to go forward and back to the end return(this.GetLastLeafAtDepth(m_traversalParameters.Root, new TreeNodePath(), this.CurrentDepthFromOrigin - 1)); } // There were some siblings, see if we can find our next target return(new TreeEvalItem <TTreeNode>(nextClosestSibling, path.CopyAndSwapEndForSibling(nextClosestSiblingIndex))); }
private TreeEvalItem <TTreeNode> GetNextRBFSCousin(TTreeNode curr, TreeNodePath path, int targetDepth) { // If we've gotten into an error state, or if we're attempting to go past root if (curr == null || curr == m_traversalParameters.Root) { return(null); } // Iterate over all siblings and build a stack of siblings for us to evaluate (popping will give us sibling closest to curr, instead of parent's index[0]) var parent = m_traversalParameters.GetParentMethod(curr); if (parent == null) { return(null); } var siblingStack = new Stack <IndexTrackedNode>(); int siblingIndex = 0; foreach (var sibling in m_traversalParameters.GetChildrenMethod(parent)) { if (sibling == curr) { break; } siblingStack.Push(new IndexTrackedNode(siblingIndex++, sibling)); } // Evaluate from closest to curr back to index zero, and call GetlastLeafAtDepth, if we find a cousin at the target depth // then that is the next BFS item to search while (siblingStack.Count > 0) { var next = siblingStack.Pop(); TreeEvalItem <TTreeNode> cousinLeaf = this.GetLastLeafAtDepth(next.Node, path.CopyAndSwapEndForSibling(next.Index), targetDepth); if (cousinLeaf != null) { return(cousinLeaf); } } // If no cousin is found, than recurse upwards, this will be evaluting parent as curr return(this.GetNextRBFSCousin(parent, path.CopyAndRemoveEnd(), targetDepth)); }