我有深度优先搜索算法的以下实现:
public static void printDFS(Node root) {
Stack<Node> stack = new Stack<Node>();
stack.push(root);
while(!stack.isEmpty()) {
Node curr = stack.pop();
System.out.println(curr.getValue()) ;
if (curr.getLeft() != null) {
stack.push(curr.getLeft());
}
if (curr.getRight() != null) {
stack.push(curr.getRight());
}
}
}
当我在看起来像这样的树上运行它时:
0
/ \
6 7
/ \ / \
5 4 3 2
我将访问的输出视为:0 - &gt; 7 - &gt; 2 - &gt; 3 - &gt; 6 - &gt; 4 - &gt; 5
这是'正确的'DFS订购吗?我原本期望输出是预订遍历(即0 - > 6 - > 5 - > 4 - > 7 - > 3 - > 2)我知道我可以通过首先推送每个子树的右边节点。但我想知道的是DFS算法中的正确的访问顺序是什么?
答案 0 :(得分:4)
正如another answer中已提到的,您的访问原因 - &gt;遍历顺序是“反转”的,因为您使用堆栈来跟踪“当前节点”。
让我引导您完成示例树:
0
/ \
6 7
/ \ / \
5 4 3 2
stack.push(root)
导致以下堆栈状态:
0: 0 <-- (root) and Top of stack
您正在弹出堆栈并将其放入curr
。在遍历方面,您现在处于这种状态:
0 <--
/ \
6 7
/ \ / \
5 4 3 2
然后,您继续将curr.getLeft()
添加到堆栈,然后curr.getRight()
。这导致了以下堆栈状态:
1: 7 <--(curr.getRight()) <-- Top of stack
0: 6 <--(curr.getLeft())
重复相同的步骤,我们得到以下遍历状态:
0
/ \
6 7<--
/ \ / \
5 4 3 2
并在添加节点后:
2: 2 <-- Top of stack
1: 3
0: 6 <-- (initial getLeft())
由于两个节点都没有子节点,从堆栈中弹出它们并输出它们会让我们跟踪遍历状态:
0
/ \
-->6 7
/ \ / \
5 4 3 2
其余部分是历史;)
正如您特别询问DFS的“正确”方式(或订购):没有。您可以定义首先穿过深度的那一侧。
答案 1 :(得分:2)
没有这样的&#34;正确的DFS订购&#34; 。 DFS的主要思想是深;在兄弟姐妹之前访问任何给定节点的孩子。一旦你深入图表并遇到一片叶子,你就会回溯并以同样的方式检查最近的兄弟姐妹。
您选择首先检查哪个子项的方式会导致不同的遍历顺序(或树)。不用说,所有遍历方法都会在图形上生成生成树。预订遍历,您正在比较的那个,可能是DFS最知名的订单(或者至少这是我所看到的)。其他人有效,但太受欢迎。
答案 2 :(得分:1)
这是一个堆栈。你最后推的是先弹出
答案 3 :(得分:0)
这是DFS的伪代码:
''” 这比搜索更像是遍历算法。 '''
Algorithm DFS(Tree):
initialize stack to contain Tree.root()
while stack is not empty:
p = stack.pop()
perform 'action' for p
for each child 'c' in Tree.children(p):
stack.push(c)
这将搜索树的所有节点是否为二进制。 要实现搜索和返回..相应地修改算法。
答案 4 :(得分:-3)
您的DFS算法有几个选项需要考虑:
Backtracking
算法进行DFS搜索。Backtracking
在向下移动时仅添加leftChild
。否则,将push()
个节点的孩子的顺序反转到Stack
,即rightChild
权利,然后leftChild
。Backtracking
时,通过创建变量nodeVistited
来避免循环,一旦节点被推入堆栈,该变量将被设置为true。否则不需要。
尝试这些更改或让我知道我将为DFS发布代码。