【问题标题】:Recursive function returning final result before all recursive calls are popped off the call stack在所有递归调用从调用堆栈弹出之前返回最终结果的递归函数
【发布时间】:2019-10-06 20:17:08
【问题描述】:

我很困惑为什么我写的这个 DFS 算法没有访问我图中的最终顶点。代码如下:

图形/顶点类

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;
    }
}

主类

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() + " ");
    }
}

调用DFS_Recursive()的结果是:

A B D E C 

我已经使用了 IntelliJ 调试器,当算法到达顶点 C 时,堆栈上仍有剩余的调用来检查 E 的邻接列表中任何剩余的未访问顶点。但是,此时它只返回结果 ArrayList,其余的递归调用将被忽略。

关于发生了什么以及如何解决它的任何想法?

【问题讨论】:

    标签: java recursion graph depth-first-search


    【解决方案1】:

    据我了解,您的实现返回得太早,以至于填充的顶点列表无法正确填充。更改实现如下。

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

    【讨论】:

      猜你喜欢
      • 2019-08-07
      • 1970-01-01
      • 2013-02-22
      • 2016-08-20
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      相关资源
      最近更新 更多