使用尾递归的后序

发布于 2024-10-27 05:06:24 字数 882 浏览 1 评论 0原文

我找到这个链接,http://www.experts-exchange.com/Programming/ Algorithms/Q_25205171.html,它提出了一种进行后序尾递归的方法。但是,它使用 2 个堆栈,有没有办法只用一个堆栈来做到这一点。谢谢!

下面是从上面的链接粘贴的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());
    }
  }

i find this link, http://www.experts-exchange.com/Programming/Algorithms/Q_25205171.html, which suggests a way to do postorder tail recursion. however, it uses 2 stacks, is there a way to do this with only one stack. thanks!

below is the java code pasted from the link above:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伴我老 2024-11-03 05:06:24

是的,但是代码的结构需要不同。递归算法的正确的基于堆栈的模拟应该将节点保留在堆栈上,直到完全遍历该节点及其子节点。堆栈应该包含一个类的实例,该类包含有关已遍历了多少个子级的信息,例如:(

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

为了简单起见,使用公共字段)。每当您将一个节点压入堆栈时,都会压入一个引用该节点且 numTraversedChildren 为 0 的 StackElement。在循环的顶部,查看(不要弹出) ) 堆栈以查找顶部元素。当且仅当 numTraversedChildren == 2 时,您才知道该节点的所有子节点都已被遍历。在这种情况下,您可以处理(在您的情况下,打印)该节点,然后弹出它。否则,将节点保留在堆栈上,递增 numTraversedChildren,并推送其左子节点(如果 numTraversedChildren 的旧值为 0)或其右子节点(如果旧值) numTraversedChildren 的值为 1)。

请注意,采用这种方法时,while 循环和堆栈上的入栈/出栈操作实际上是在模拟函数调用:入栈是调用,出栈是返回,并且堆栈维护所有的操作。每个函数调用的参数和局部变量。堆栈顶部的元素始终代表当前正在执行的函数。

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. If and only if numTraversedChildren == 2, you know that all children of this node have been traversed. 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).

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. The element at the top of the stack always represents the function that is currently executing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文