简体   繁体   English

使用尾递归的后订单

[英]postorder using tail recursion

i find this link, http://www.experts-exchange.com/Programming/Algorithms/Q_25205171.html , which suggests a way to do postorder tail recursion. 我在http://www.experts-exchange.com/Programming/Algorithms/Q_25205171.html上找到了此链接,该链接建议了一种进行后尾递归的方法。 however, it uses 2 stacks, is there a way to do this with only one stack. 但是,它使用2个堆栈,有没有办法仅用一个堆栈来完成此操作。 thanks! 谢谢!

below is the java code pasted from the link above: 下面是从上面的链接粘贴的Java代码:

public static final <T> void postorder(Tree<T> root) {
    Stack<Tree<T>> stack = new Stack<Tree<T>>();
    Stack<Tree<T>> traversal = new Stack<Tree<T>>();
    stack.push(root);
    while (!stack.isEmpty()) {
      Tree<T> node = stack.pop();
      if (node.right != null) 
        stack.push(node.right);
      }
      if (node.left != null) {
        stack.push(node.left);
      }
      traversal.push(node);
    }
    while (!traversal.isEmpty()) {
      System.out.println(traversal.pop().value.toString());
    }
  }

Yes, but the code needs to be structured differently. 是的,但是代码的结构需要不同。 A proper stack-based simulation of a recursive algorithm should keep a node on the stack until the node and its children have been completely traversed. 适当的基于堆栈的递归算法仿真应将节点保留在堆栈上,直到已完全遍历该节点及其子节点为止。 The stack should contain instances of a class that contains information about how many children have been traversed, say: 堆栈应包含一个类的实例,该类包含有关已遍历多少个子代的信息,例如:

public class StackElement<T> {
    public Tree<T> node;
    public int numTraversedChildren;
}

(using public fields for simplicity). (为简单起见,使用公共字段)。 Whenever you push a node onto the stack, push a StackElement that refers to that node and where numTraversedChildren is 0. In the top of the loop, peek (don't pop) the stack to find the top element. 当你把一个节点到堆栈,推StackElement是指节点以及numTraversedChildren是0。在循环的顶部,PEEK(不弹出)堆栈来找到顶级的元素。 If and only if numTraversedChildren == 2 , you know that all children of this node have been traversed. 当且仅当numTraversedChildren == 2 ,您知道该节点的所有子级都已遍历。 In that case, you can process (in your case, print) that node and then pop it. 在这种情况下,您可以处理(在您的情况下为打印)该节点,然后将其弹出。 Otherwise, keep the node on the stack, increment numTraversedChildren , and push either its left child (if the old value of numTraversedChildren was 0) or its right child (if the old value of numTraversedChildren was 1). 否则,保持节点栈上,增加numTraversedChildren ,并推动其要么左子(如果旧值numTraversedChildren为0),或者它的右子(如果旧值numTraversedChildren为1)。

Note that when this approach is followed, the while loop and the push/pop operations on the stack are effectively simulating function calls: a push is a call, a pop is a return, and the stack maintains all parameters and local variables for each function invocation. 请注意,采用这种方法时, while循环和堆栈上的push / pop操作有效地模拟了函数调用:push是调用,pop是返回,并且堆栈维护每个函数的所有参数和局部变量调用。 The element at the top of the stack always represents the function that is currently executing. 堆栈顶部的元素始终表示当前正在执行的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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