如何迭代二叉树?
现在我
private static void iterateall(BinaryTree foo) {
if(foo!= null){
System.out.println(foo.node);
iterateall(foo.left);
iterateall(foo.right);
}
}
可以将其更改为迭代而不是递归吗?
Right now I have
private static void iterateall(BinaryTree foo) {
if(foo!= null){
System.out.println(foo.node);
iterateall(foo.left);
iterateall(foo.right);
}
}
Can you change it to Iteration instead of a recursion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您正在寻找的是后继算法。
它的定义方式如下:
正如你所看到的,要使其工作,你需要一个父节点指针。
示例:
(1)
(1)< /code> 没有右子树,我们转到
(3)
。这是右转,因此(3)
是下一个。(3)
有一个右子树,因此该子树中最左边的节点是下一个:(4)
。(4)
没有右子树,因此我们转到(6)
。这是右转,所以接下来是(6)
。(6)
有一个右子树,因此该子树中最左边的节点是下一个:(7)
。(7)
没有右子树,因此我们转到(6)
。这是左转,因此我们继续前往(3)
。这是左转,因此我们继续前往(8)
。这是右转,所以接下来是(8)
。(8)
有一个右子树,因此该子树中最左边的节点是下一个:(10)
。(10)
有一个右子树,因此该子树中最左边的节点是下一个:(13)
。(13)
没有右子树,因此我们转到(14)
。这是右转,所以接下来是(14)
。(14)
没有右子树,因此我们转到(10)
。这是左转,因此我们继续前往(8)
。这是左转,所以我们想继续向上,但由于(8)
没有父节点,所以我们已经到达终点了。(14)
没有后继者。伪代码
Java 代码
这是上述算法的简单实现:
然后您可以拥有如下所示的测试工具:
此打印:
另请参阅
What you're looking for is a successor algorithm.
Here's how it can be defined:
As you can see, for this to work, you need a parent node pointer.
Example:
(1)
(1)
has no right subtree, we go up to(3)
. This is a right turn, so(3)
is next.(3)
has a right subtree, the leftmost node in that subtree is next:(4)
.(4)
has no right subtree, we go up to(6)
. This is a right turn, so next is(6)
.(6)
has a right subtree, the leftmost node in that subtree is next:(7)
.(7)
has no right subtree, we go up to(6)
. This is a left turn, so we continue going up to(3)
. This is a left turn, so we continue going up to(8)
. This is a right turn, so next is(8)
.(8)
has a right subtree, the leftmost node in that subtree is next:(10)
.(10)
has a right subtree, the leftmost node in that subtree is next:(13)
.(13)
has no right subtree, we go up to(14)
. This is a right turn, so next is(14)
.(14)
has no right subtree, we go up to(10)
. This is a left turn, so we continue going up to(8)
. This is a left turn, so we want to continue going up, but since(8)
has no parent, we've reached the end.(14)
has no successor.Pseudocode
Java code
Here's a simple implementation of the above algorithm:
Then you can have a test harness like this:
This prints:
See also
您可以使用显式堆栈。伪代码:
但这并不比递归代码真正优越(除了代码中缺少基本条件)。
You can, using an explicit stack. Pseudocode:
But this isn’t really superior to the recursive code (except for the missing base condition in your code).
当然,您有两种通用算法,深度优先搜索和广度优先搜索。
如果遍历顺序对你来说不重要,那么先考虑广度,这样迭代更容易实现。你的算法应该看起来像这样。
Sure, you have two general algorithms, depth first search and breadth first search.
If order of traversal is not important to you, go for breadth first, it's easier to implement for iteration. You're algorithm should look something like this.
与每次递归一样,您可以使用额外的数据结构 - 即堆栈。
解决方案的草图:
As with every recursion, you can use additional data structure - i.e. the stack.
A sketch of the solution:
我有一棵树(不是二叉树)并最终用这个非常简单的算法解决了它。其他解决方案使用的左和右与示例无关,甚至没有实现。
我的结构是:每个父节点都包含子节点列表,每个子节点都包含一个指向父节点的指针。很常见...
经过一系列重构后,我使用 Kotlin 提出了以下示例。转换为您选择的语言应该很简单。
辅助函数
首先,节点必须提供 2 个简单的函数。这将根据您的 Node 类的实现而有所不同:
leftMost - 这是第一个子节点。如果该节点有子节点,则它是第一个子节点,依此类推。如果没有子节点,则返回 this。
nextSibling - 该节点的下一个兄弟节点,或 NULL
迭代
迭代从根的最左边开始。
然后检查下一个兄弟姐妹。
就是这样。
这是一个 Kotlin 迭代器函数。
这是相同的 next() 函数,但对于那些不熟悉语法的人来说,没有处理 NULL 值的 Kotlin 简写。
I had a tree (not binary) and eventually solved it with this very simple algorithm. The other solutions used left and right that were not relevant or even implemented in the examples.
My structure was: nodes with each parent containing list of children, and each child containing a pointer back to the parent. Pretty common...
After a bunch of refactoring, I came up with the following example using Kotlin. It should be trivial to convert to your language of choice.
Helper Functions
First, the node must provide 2 simple functions. This will vary depending on your Node class' implementation:
leftMost - This is the first child node. If that node has children, it's first child, etc. If no children, return this.
nextSibling - The next sibling of this node, or NULL
The Iteration
The iteration starts with the leftMost of the root.
Then inspect the next sibling.
That's it.
Here is a Kotlin iterator function.
Here is the same next() function, but without the Kotlin shorthand for dealing with NULL values, for those that are not hip to the syntax.
是的,您可以将其更改为迭代而不是递归,但是这样会变得更加复杂,因为您需要有某种方法来记住从当前节点返回的位置。在递归情况下,Java 调用堆栈会处理该问题,但在迭代解决方案中,您需要构建自己的堆栈,或者可能在节点中存储反向指针。
Yes, you can change it to iteration instead of a recursion, but then it gets much more complicated, since you need to have some way to remember where to go back from the current node. In the recursive case, the Java call stack handles that, but in an iterative solution you need to build your own stack, or perhaps store back pointers in the nodes.