PostOrder Traversal使用一个堆栈

时间:2018-05-15 21:09:26

标签: c++ algorithm binary-tree postorder

我正在尝试使用堆栈了解DFS树遍历。我发现将递归解决方案转换为迭代转换解决方案非常直观。但是,我发现使用此链接了解后序遍历并不困难。 https://www.geeksforgeeks.org/iterative-postorder-traversal-using-stack/。是否有一种直观而简单的思考方式?  预购代码:

void iterativePreorder(node *root)
{
    // Base Case
    if (root == NULL)
       return;

    // Create an empty stack and push root to it
    stack<node *> nodeStack;
    nodeStack.push(root);

    /* Pop all items one by one. Do following for every popped item
       a) print it
       b) push its right child
       c) push its left child
    Note that right child is pushed first so that left is processed first */
    while (nodeStack.empty() == false)
    {
        // Pop the top item from stack and print it
        struct node *node = nodeStack.top();
        printf ("%d ", node->data);
        nodeStack.pop();

        // Push right and left children of the popped node to stack
        if (node->right)
            nodeStack.push(node->right);
        if (node->left)
            nodeStack.push(node->left);
    }
}

3 个答案:

答案 0 :(得分:3)

使用预订遍历,代码

  • 显示当前节点的数据
  • 遍历左子树
  • 遍历正确的子树

使用后期遍历,代码

  • 遍历左子树
  • 遍历正确的子树
  • 显示当前节点的数据

所以区别在于,在执行订单后遍历时,数据需要存储在堆栈中,以便最后打印。有几种不同的方法可以实现这一目标。一种方法是更改​​堆栈实现以区分子指针和数据指针。

弹出子指针时,操作为

  • 将当前节点作为数据指针推送
  • 将右侧节点作为子指针推送
  • 将左节点作为子指针推送

弹出数据指针时,操作为

  • 显示节点的数据

然后通过将根节点作为子指针来启动遍历。

答案 1 :(得分:0)

尽管代码更难,但是迭代后顺序比其他遍历更直观,因为其他的遍历已经重构,而其他遍历无法重构。

在这里使用第一个解决方案: https://articles.leetcode.com/binary-tree-post-order-traversal/

直觉是递归函数具有迭代方法没有的信息,主要是遍历的方向。当递归函数执行或后坐时,它通过执行的代码行知道它来自哪里。 IE(如果您正在打印或处理当前节点),您知道您已经访问了子节点,因为它们已经被递归调用了。

一个迭代解决方案可以通过使用“上一个”指针进行跟踪,因此您会看到“如果上一个不是当前节点的子节点”的检查,则意味着您正在向下遍历并且需要向左走。其他可能性是前一个来自左或右子节点。处理完所有案件后,您便有了解决方案。

答案 2 :(得分:0)

请在下面使用Java中的一个堆栈查找PostOrder Traversal的代码段

public class PostOrderWithoutRecurssion {

    static Stack<Node> stack = new Stack<Node>();

    static class Node{
        int data;
        int status;
        Node left, right;

        Node(int data){
            this.data = data;
            this.status=0;
        }
    }//end class Node

    public static void main(String[] args) {
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(6);
        root.right.right = new Node(7);
        root.left.left.left = new Node(8);
        root.left.left.right = new Node(9);

        postOrderWithoutRecurssion(root);
    }//end main

    public static void postOrderWithoutRecurssion(Node root) {
        Node temp = root;

        while(temp!=null || stack.size()>0) {

            while(temp!=null) {
                temp.status = 1;
                stack.push(temp);
                temp = temp.left;
            }

            temp = stack.pop();

            if(null==temp.left && null == temp.right) {
                temp.status = 2;
                System.out.println(temp.data);
            }else if(null != temp.right) {
                if(temp.left.status==2 && temp.right.status==2) {
                    temp.status = 2;
                    System.out.println(temp.data);
                    temp = null;
                }else {
                    if(temp.status!=1) {
                        temp.status = 1;
                        stack.push(temp);
                    }else {
                        stack.push(temp);
                    }
                }
            }

            if(null!=temp) {
                temp = temp.right;    
            }

        }
    }//end postOrderWithoutRecurssion
}