Нечетное упорядочение в итеративной DFS против рекурсивной DFS - PullRequest
2 голосов
/ 07 октября 2011

Я решаю эту проблему 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 43 2 6

в то время как это должно быть (в соответствии с выходным образцом задачи и рекурсивной версией):

1 3 2 6 4

Что здесь происходит?Почему устранение рекурсии изменяет порядок посещаемых узлов?

-> Полный код в проекте Netbeans .

Ответы [ 2 ]

3 голосов
/ 16 октября 2012

Проверьте свои graph.adjacencies.get(V), дают ли они одинаковый ответ для обоих случаев?Если это так, то рекурсивный вызов и вызов стека будут давать разные результаты.Например, дерево типа:

      1
    2   3
  4

будет иметь порядок 1->3->2->4 для версии стека, а порядок 1->2->4->3 для рекурсивной версии, предполагая, что graph.adjacencies.get(V) всегда сначала возвращает левого потомка.

1 голос
/ 07 октября 2011

Из-за стека. Это First-In, Last-Out, так что вы будете проходить через дочерние узлы в обратном порядке, в котором вы добавили их в стек.

Скажем, 2 ребенка корня - А и В в следующем порядке (слева направо).

Первый алгоритм:

  1. Ручка рута
  2. Добавить A в стек
  3. Добавить B в стек
  4. Извлечение из стека (так что B, потому что стек это FILO)

Второй алгоритм:

  1. Ручка рута
  2. ручка A
  3. ... обращаться с детьми А
  4. Ручка B

Вы можете заменить свой стек реализацией очереди, которая является FIFO, и все должно быть в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...