【问题标题】:PostOrder Traversal using one stackPostOrder Traversal 使用一个堆栈
【发布时间】:2018-05-15 21:09:26
【问题描述】:

我正在尝试使用堆栈来理解 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);
    }
}

【问题讨论】:

  • 预购和后购没有太大区别。如果您显示预购遍历的代码可能会有所帮助。然后有人可以建议如何调整该代码以适应 postorder。
  • @user3386109 已编辑
  • @user3386109:回复:“预购和后购之间没有太大区别”:我不同意。您可能正在考虑递归实现(它们几乎是相同的),但是使用迭代堆栈实现,预排序可以比后排序更简单地实现。

标签: c++ algorithm binary-tree postorder


【解决方案1】:

带前序遍历,代码

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

后序遍历,代码

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

所以不同的是,在进行后序遍历时,需要将数据存入栈中,这样才能最后打印。有几种不同的方法可以实现这一点。一种方法是更改​​堆栈实现以区分子指针和数据指针。

当一个子指针被弹出时,动作是

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

当一个数据指针被弹出时,动作是

  • 显示节点的数据

然后通过将根节点作为子指针推入开始遍历。

【讨论】:

    【解决方案2】:

    虽然代码更难,但迭代后序可能比其他遍历更直观,因为其他遍历已经被重构,而这个不能被类似地重构。

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

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

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

    【讨论】:

      【解决方案3】:

      请在下面找到Java中使用一个堆栈的PostOrder Traversal的代码sn-p

      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
      }
      

      【讨论】:

        猜你喜欢
        • 2015-01-14
        • 2013-12-26
        • 1970-01-01
        • 1970-01-01
        • 2021-07-15
        • 2013-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多