簡體   English   中英

非遞歸后遍歷

[英]Non-recursive post order traversal

我在某些網站上看到了以下訂單遍歷算法...這似乎是正確的。 我只想驗證此算法是否正常工作-該算法是否正確無誤地進行訂單遍歷?

void postOrderTraversal(Tree *root)
{
    node * previous = null;
    node * s = null;
    push(root);
    while( stack is not empty )
    {
        s = pop();

        if(s->right == null and s->left == null)
        {
            previous = s;
            process s;
        }
        else
        {
            if(s->right == previous or s->left == previous)
            {
                previous = s;
                process s;
            }
            else
            {
                push( s );
                if(s->right) { push(s->right); }
                if(s->left)  { push(s->left);  }
            }
        }
    }
}

嘗試編寫迭代的有序,有序和后序二進制遍歷方法版本。 然后,您將看到將其相應的遞歸版本轉換為迭代版本的模式或方法。

關鍵在於堅持一些基本規則:
-使用節點選擇(例如,currentNode = currentNode-> Left,然后再次循環),以便立即遍歷節點。
-使用堆棧來記住以后需要訪問或重新訪問的節點。
-如果需要“重新訪問”某個節點,請檢測/保留狀態,以便您可以指示在下一次迭代中是否需要“處理”下一個節點,還是應該先訪問一個或多個子節點,然后才能訪問該節點處理。

如果遵守這些規則,則可以輕松完成任務。

這是迭代后遍歷的示例。 忽略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);
        }
    }

no no prev不應以null開頭,例如:對於具有節點5 2 1 3 7 6 8 0的bst,它將不認為是零,因為在1時,它的右邊是null,這次以前也將是null,因此它將不考慮其左子節點即0寫以前=任何值,但不為空

這是工作代碼

Stack s=new Stack();
    while(true){
       if(root!=null){
           s.push(root);
           root=root.left;
       }
       else{
            if(s.top().right==NULL){
               root=s.top();
               s.pop();
               System.out.println(root.data);
               if(root==s.top().right){
                    System.out.println(s.top().data);
                    s.pop();
               }
            }
       if(!s.empty())
          root=s.top().right;
       else 
          root=NULL;

       }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM