简体   繁体   English

迭代DFS与递归DFS中的奇数排序

[英]Odd ordering in iterative DFS vs recursive DFS

I'm solving this dfs/bfs problem. 我正在解决这个dfs / bfs问题。

I wrote both an iterative version and a recursive version of DFS. 我写了DFS的迭代版本和递归版本。

The order of node visiting is different and I don't get why. 节点访问的顺序不同,我不知道为什么。

iterative DFS: 迭代DFS:

static void DFS (Integer root, Graph graph){

      //  System.out.println("DFS");

        HashSet <Integer> explored = new HashSet<Integer>();
             explored.add(root);

        Stack<Integer> stack = new Stack<Integer>();
              stack.add(root);

        int v; int w;


        while (!stack.isEmpty()){

            v=stack.pop();
            explored.add(v);

            System.out.print(v + " ");
           // for (int i=graph.adjacencies.get(v).size()-1; i>=0; i--) {
            for (int i=0; i < graph.adjacencies.get(v).size(); i++) {
                w = graph.adjacencies.get(v).get(i);

                if (!explored.contains(w)){

                    stack.add(w);
                    explored.add(w);
                }
            }

        }System.out.println();
    } 

recursive DFS: 递归DFS:

static void DFS_2 (Integer root, Graph graph){

//        System.out.println("DFS_2");

        int v; int w;

        v = root;

        graph.explored.add(v);

            System.out.print(v + " ");
            for (int i=0; i < graph.adjacencies.get(v).size(); i++) {

                w = graph.adjacencies.get(v).get(i);

                if (!graph.explored.contains(w)){

                    graph.explored.add(w);
                    DFS_2(w, graph);
                }
            }


    }

On the tutorial problem my output on the iterative DFS version is 关于教程问题,我在迭代DFS版本上的输出是

1 4 3 2 6 1 4 3 2 6

while it should be (according to the problem sample output and the recursive version): 它应该是(根据问题样本输出和递归版本):

1 3 2 6 4 1 3 2 6 4

What's happening here? 这里发生了什么事? Why is eliminating the recursion altering the visited node order? 为什么消除递归会更改访问节点的顺序?

-> Full code on a Netbeans project . -> Netbeans项目上的完整代码

Check your graph.adjacencies.get(V) , does they give you the same response for the both cases? 检查您的graph.adjacencies.get(V) ,对于这两种情况,它们是否给您相同的响应? If so, then recursive call and stack call will give different results. 如果是这样,那么递归调用和堆栈调用将给出不同的结果。 For example, a tree like: 例如,像这样的树:

      1
    2   3
  4

will have the order 1->3->2->4 for the stack version, and the order of 1->2->4->3 for the recursive version, assuming graph.adjacencies.get(V) always returns the left child first. 假设graph.adjacencies.get(V)始终返回,则堆栈版本的顺序为1->3->2->4 ,而递归版本的顺序为1->2->4->3 。先离开孩子。

Because of the Stack. 由于堆栈。 It is First-In, Last-Out, so you'll be going through a nodes' children in the reversed order in which you added them to the stack. 它是先进先出的,因此您将按照相反的顺序遍历节点的子级,将它们添加到堆栈中。

Say the 2 kids of the root are A and B, in this order (left-to-right). 假设根的两个孩子依次是A和B(从左到右)。

First algo: 第一算法:

  1. Handle root 处理根
  2. Add A to stack 将A添加到堆栈
  3. Add B to stack 将B添加到堆栈
  4. Pop from stack (so B, because the stack is FILO) 从堆栈弹出(所以B,因为堆栈是FILO)

Second algo: 第二算法:

  1. Handle root 处理根
  2. Handle A 手柄A
  3. ... handle A's kids ...处理A的孩子
  4. Handle B 手柄B

You can replace your Stack with a Queue implementation that is FIFO and it should be ok. 您可以将Stack替换为FIFO的Queue实现,应该可以。

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

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