深度优先搜索二叉树

时间:2014-11-17 06:56:04

标签: algorithm

我有深度优先搜索算法的以下实现:

 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算法中的正确的访问顺序是什么?

5 个答案:

答案 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算法有几个选项需要考虑:

  1. 首先,使用Backtracking算法进行DFS搜索。
  2. 如果使用Backtracking在向下移动时仅添加leftChild。否则,将push()个节点的孩子的顺序反转到Stack,即rightChild权利,然后leftChild
  3. 再次使用Backtracking时,通过创建变量nodeVistited来避免循环,一旦节点被推入堆栈,该变量将被设置为true。否则不需要。 尝试这些更改或让我知道我将为DFS发布代码。