Нечетный порядок в итеративной DFS по сравнению с рекурсивной DFS

Я решаю эту проблему dfs/bfs.

Я написал как итеративную версию, так и рекурсивную версию 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();
    } 

рекурсивный поиск в глубину:

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.


person andandandand    schedule 06.10.2011    source источник


Ответы (2)


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

      1
    2   3
  4

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

person karida    schedule 16.10.2012

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

Скажем, 2 ребенка корня — это A и B, в этом порядке (слева направо).

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

  1. Обработать корень
  2. Добавить А в стек
  3. Добавить B в стек
  4. Выталкивать из стека (так что B, потому что стек FILO)

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

  1. Обработать корень
  2. Ручка А
  3. ... справиться с детьми А
  4. Ручка Б

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

person Sorin    schedule 07.10.2011