简体   繁体   中英

Non-recursive post order traversal

I saw the following post order traversal algorithm in some website... it seems to be correct. I just want to verify that this algorithm works correctly — is this algorithm correct for post order traversal without recursion?

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);  }
            }
        }
    }
}

Try to write iterative versions of pre-order, in-order, and post-order binary traversal methods. You will then see the pattern or methodology of converting their corresponding recursive versions into the iterative versions.

Key point is sticking to some basic rules:
- Use node selection (eg, currentNode = currentNode->Left before reiterating the loop, etc.) for immediate node traversal.
- Use stack to remember nodes that need to be visited or revisited later.
- If a node need to be "REvisited," detecting / keeping the state so that you can indicate whether the next node needs to be "processed" in next iteration or one of more of the child nodes should be visited before the node can be processed.

If you stick to these rules, you can esily accomplish the tasks.

Here is an example of the iterative post-order traversal. Ignore BinarySearchTree - it works for any binary trees.

    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写以前=任何值,但不为空

Here is the working code

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;

       }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM