Fun TreeBreadthFirstTraverse(TTreeNode& tree_node, Fun func) { ETreeTraverseCode stop_scan; stop_scan = func(tree_node); switch(stop_scan) { case eTreeTraverseStop: case eTreeTraverseStepOver: return func; case eTreeTraverse: break; } if ( stop_scan ) return func; TTreeNode* tr = &tree_node; typedef typename TTreeNode::TNodeList_I TTreeNodeIterator; TTreeNodeIterator it = tr->SubNodeBegin(); TTreeNodeIterator it_end = tr->SubNodeEnd(); if (it == it_end) return func; queue<TTreeNodeIterator> tree_queue; while (it != it_end) tree_queue.push(it++); while (!tree_queue.empty()) { it = tree_queue.front(); // get oldest node on queue tr = *it; tree_queue.pop(); // take oldest node off stop_scan = eTreeTraverse; if (tr) { stop_scan = func(*tr); switch(stop_scan) { case eTreeTraverseStop: return func; case eTreeTraverse: case eTreeTraverseStepOver: break; } } // Add children (if any) of node to queue if (stop_scan != eTreeTraverseStepOver && !tr->IsLeaf()) { it = tr->SubNodeBegin(); it_end = tr->SubNodeEnd(); while (it != it_end) tree_queue.push(it++); } } return func; }
Fun TreeDepthFirstTraverse(TTreeNode& tree_node, Fun func) { int delta_level = 0; ETreeTraverseCode stop_scan; stop_scan = func(tree_node, delta_level); switch (stop_scan) { case eTreeTraverseStop: case eTreeTraverseStepOver: return func; case eTreeTraverse: break; } if (stop_scan) return func; delta_level = 1; TTreeNode* tr = &tree_node; typedef typename TTreeNode::TNodeList_I TTreeNodeIterator; TTreeNodeIterator it = tr->SubNodeBegin(); TTreeNodeIterator it_end = tr->SubNodeEnd(); if (it == it_end) return func; stack<TTreeNodeIterator> tree_stack; while (true) { tr = (TTreeNode*)*it; stop_scan = eTreeTraverse; if (tr) { stop_scan = func(*tr, delta_level); switch (stop_scan) { case eTreeTraverseStop: return func; case eTreeTraverse: case eTreeTraverseStepOver: break; } } if ( (stop_scan != eTreeTraverseStepOver) && (delta_level >= 0) && (!tr->IsLeaf())) { // sub-node, going down tree_stack.push(it); it = tr->SubNodeBegin(); it_end = tr->SubNodeEnd(); delta_level = 1; continue; } ++it; if (it == it_end) { // end of level, going up if (tree_stack.empty()) { break; } it = tree_stack.top(); tree_stack.pop(); tr = (TTreeNode*)*it; it_end = tr->GetParent()->SubNodeEnd(); delta_level = -1; continue; } // same level delta_level = 0; } // while func(tree_node, -1); return func; }