Recursive function returning final result before all recursive calls are popped off the call stack

PumpkinBreath :

I am confused about why this DFS algorithm I've written is not visiting the final vertex in my graph. Here is the code:

Graph/Vertex Class

import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;

public class Graph {

    private HashMap<Vertex, ArrayList<Vertex>> adjacencyList;

    public Graph() {
        this.adjacencyList = new HashMap<>();
    }

    public void addVertex(Vertex vertex) {
        if (!adjacencyList.containsKey(vertex)) {
            adjacencyList.put(vertex, new ArrayList<>());
        }
    }

    public void addEdge(Vertex vertex1, Vertex vertex2) {
        this.adjacencyList.get(vertex1).add(vertex2);
        this.adjacencyList.get(vertex2).add(vertex1);
    }

    public HashMap<Vertex, ArrayList<Vertex>> getAdjacencyList() {
        return adjacencyList;
    }

    public void printAdjacencyList(Vertex vertex) {
        System.out.print(vertex.getValue() + ": ");
        for (Vertex v : adjacencyList.get(vertex)) {
            System.out.print(v.getValue());
        }
        System.out.println();
    }

    public ArrayList<Vertex> DFS_Recursive(Vertex start) {
        ArrayList<Vertex> result = new ArrayList<>();
        HashMap<Vertex, Boolean> visited = new HashMap<>();
        for (Vertex v : adjacencyList.keySet()) {
            visited.put(v, false);
        }
        return DFS_Recursive_Utility(start, result, visited);
    }

    private ArrayList<Vertex> DFS_Recursive_Utility(Vertex vertex, ArrayList<Vertex> results, HashMap<Vertex, Boolean> visited) {
        if (vertex == null) {
            return null;
        }
        visited.put(vertex, true);
        results.add(vertex);
        for (Vertex v : adjacencyList.get(vertex)) {
            if (!visited.get(v)) {
                return DFS_Recursive_Utility(v, results, visited);
            }
        }
        return results;
    }
}

class Vertex<E> {

    private E value;

    public Vertex(E value) {
        this.value = value;
    }

    public E getValue() {
        return value;
    }
}

Main Class

public static void main(String[] args) {

    Vertex<String> a = new Vertex<>("A");
    Vertex<String> b = new Vertex<>("B");
    Vertex<String> c = new Vertex<>("C");
    Vertex<String> d = new Vertex<>("D");
    Vertex<String> e = new Vertex<>("E");
    Vertex<String> f = new Vertex<>("F");

    Graph graph = new Graph();
    graph.addVertex(a);
    graph.addVertex(b);
    graph.addVertex(c);
    graph.addVertex(d);
    graph.addVertex(e);
    graph.addVertex(f);
    graph.addEdge(a, b);
    graph.addEdge(a, c);
    graph.addEdge(b, d);
    graph.addEdge(c, e);
    graph.addEdge(d, e);
    graph.addEdge(d, f);
    graph.addEdge(e, f);
    System.out.println();
    for (Vertex v : graph.getAdjacencyList().keySet()) {
        graph.printAdjacencyList(v);
    }
    System.out.println();
    for (Vertex v : graph.DFS_Recursive(a)) {
        System.out.print(v.getValue() + " ");
    }
}

The result of calling DFS_Recursive() is:

A B D E C 

I have gone through with the IntelliJ debugger and when the algorithm hits vertex C, there are still remaining calls on the stack for it to check any remaining un-visited vertices in E's adjacency list. However, at that point it just returns the results ArrayList and the remaining recursive calls are ignored.

Any ideas on whats happening and how to fix it?

Codor :

To my understanding, your implementation returns too early such that the list of populated vertices does not get populated correctly. Change the implementation as follows.

public ArrayList<Vertex> DFS_Recursive(Vertex start) {
    ArrayList<Vertex> result = new ArrayList<>();
    HashMap<Vertex, Boolean> visited = new HashMap<>();
    for (Vertex v : adjacencyList.keySet()) {
        visited.put(v, false);
    }
    DFS_Recursive_Utility(start, result, visited);
    return result;
}


private void DFS_Recursive_Utility(Vertex vertex,
                                   ArrayList<Vertex> results,
                                   HashMap<Vertex, Boolean> visited) {
        if (vertex == null) {
            return;
        }
        visited.put(vertex, true);
        results.add(vertex);
        for (Vertex v : adjacencyList.get(vertex)) {
            if (!visited.get(v)) {
            DFS_Recursive_Utility(v, results, visited);
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=149088&siteId=1