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

发布于 2024-12-08 20:07:32 字数 1787 浏览 0 评论 0原文

我正在解决这个 dfs/bfs 问题。

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

递归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);
                }
            }


    }

在教程问题上,我在迭代DFS版本上的输出是

1 4 3 2 6,

而它应该是(根据问题示例输出和递归版本):

1 3 2 6 4

这里发生了什么?为什么消除递归会改变访问节点的顺序?

->Netbeans 项目的完整代码

I'm solving this dfs/bfs problem.

I wrote both an iterative version and a recursive version of DFS.

The order of node visiting is different and I don't get why.

iterative 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:

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

1 4 3 2 6

while it should be (according to the problem sample output and the recursive version):

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.

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

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

发布评论

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

评论(2

清晨说晚安 2024-12-15 20:07:32

检查您的graph.adjaccies.get(V),这两种情况它们是否给您相同的响应?如果是这样,那么递归调用和堆栈调用将给出不同的结果。例如,像这样的树:

      1
    2   3
  4

堆栈版本的顺序为 1->3->2->4,而堆栈版本的顺序为 1->2-> ;4->3 对于递归版本,假设 graph.adjaccies.get(V) 始终首先返回左子节点。

Check your graph.adjacencies.get(V), does they give you the same response for the both cases? 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.

毁虫ゝ 2024-12-15 20:07:32

因为堆栈。它是先进后出的,因此您将以与将节点添加到堆栈的顺序相反的顺序遍历节点的子节点。

假设根的 2 个孩子是 A 和 B,按这个顺序(从左到右)。

第一个算法:

  1. 处理根
  2. 将 A 添加到堆栈
  3. 将 B 添加到堆栈
  4. 从堆栈中弹出(所以 B,因为堆栈是 FILO)

第二个算法:

  1. 处理根
  2. 处理 A
  3. ...处理 A 的孩子
  4. 处理 B

您可以用队列实现替换您的堆栈那是 FIFO 应该没问题。

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).

First algo:

  1. Handle root
  2. Add A to stack
  3. Add B to stack
  4. Pop from stack (so B, because the stack is FILO)

Second algo:

  1. Handle root
  2. Handle A
  3. ... handle A's kids
  4. Handle B

You can replace your Stack with a Queue implementation that is FIFO and it should be ok.

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