嘗試編寫預訂,按序和後序二進制遍歷方法的迭代版本。然後您將看到將相應的遞歸版本轉換爲迭代版本的模式或方法。
關鍵點是粘到一些基本規則:
- 使用節點選擇(例如,currentNode = currentNode->重申循環等前左),用於即時節點遍歷。
- 使用堆棧記住稍後需要訪問或重新訪問的節點。
- 如果某個節點需要「重新訪問」,則檢測/保持該狀態,以便您可以指示下一個迭代中是否需要「處理」下一個節點,或者是否應該在節點可以被處理。
如果你堅持這些規則,你可以esily完成任務。
下面是一個迭代後序遍歷的例子。忽略BinarySearchTree - 適用於任何二叉樹。
public static IEnumerator<BinarySearchTreeNode<T>> GetPostOrderTraverseEnumerator(BinarySearchTreeNode<T> root)
{
if (root == null)
{
throw new ArgumentNullException("root");
}
Stack<BinarySearchTreeNode<T>> stack = new Stack<BinarySearchTreeNode<T>>();
BinarySearchTreeNode<T> currentNode = root;
// If the following flag is false, we need to visit the child nodes first
// before we process the node.
bool processNode = false;
while (true)
{
// See if we need to visit child nodes first
if (processNode != true)
{
if (currentNode.Left != null)
{
// Remember to visit the current node later
stack.Push(currentNode);
if (currentNode.Right != null)
{
// Remember to visit the right child node later
stack.Push(currentNode.Right);
}
// Visit the left child
currentNode = currentNode.Left;
continue;
}
else if (currentNode.Right != null)
{
// Remember to visit the current node later
stack.Push(currentNode);
// Visit the right child
currentNode = currentNode.Right;
continue;
}
}
// Process current node
yield return currentNode;
// See if we are done.
if (stack.Count == 0)
{
break;
}
// Get next node to visit from the stack
BinarySearchTreeNode<T> previousNode = currentNode;
currentNode = stack.Pop();
// See if the next node should be processed or not
// This can be determined by the fact that either of the current node's child nodes
// has just been processed now.
processNode = (previousNode == currentNode.Left || previousNode == currentNode.Right);
}
}
你閱讀Algogeeks線程的休息嗎? http://www.mail-archive.com/[email protected]/msg03546.html – APC 2009-09-24 12:29:57
它不是*語法*遞歸,因爲它是模擬*遞歸PUSH和POP。 – RBarryYoung 2009-09-30 17:44:15
巴里,我會認爲,甚至沒有必要用「模擬」來限定它。 – 2009-09-30 17:58:50