StackOverflow错误与图数据结构

时间:2014-04-23 17:35:42

标签: java graph stack-overflow

所以我正在尝试编写一个方法来查看某个顶点是否是循环的一部分,但是我得到了这个错误

java.lang.StackOverflowError
at java.lang.Integer.compareTo(Unknown Source)
at java.lang.Integer.compareTo(Unknown Source)
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at graph.EdgeSet.neighbors(EdgeSet.java:42)
at graph.Graph.getNeighbors(Graph.java:127)
at graph.Graph.cycleHelper(Graph.java:164)
at graph.Graph.cycleHelper(Graph.java:171)

这是我的方法

public boolean isInCycle(V vertex) throws IllegalArgumentException {

    if (!hasVertex(vertex)) {
        throw new IllegalArgumentException();
    }
    Iterator<Vertex<V>> v = vertexMap.keySet().iterator();
    while (v.hasNext()) {
        Vertex<V> vert = v.next();
        vert.activated = false;
        vert.through = false;
    }
    return cycleHelper(vertex);
}

private boolean cycleHelper(V vertex) {
    Vertex<V> ve = vertexMap.get(new Vertex<V>(vertex)).vertex();
    ve.activated = true;
    Iterator<V> n = getNeighbors(vertex).iterator();
    while (n.hasNext()) {
        V vert = n.next();
        Vertex<V> curr = vertexMap.get(new Vertex<V>(vert)).vertex();
        if (curr.activated)
            return true;
        else {
            return cycleHelper(curr.vertex());

            }
    }

    return false;
}

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

编辑:我的第一个回答提到了无限递归,但这不是这里的情况:activated标志已经旨在防止这种情况发生。

StackOverflowError可能有两个主要原因:第一个是无限递归(这里已经排除了)。第二个是调用堆栈上的调用太多了。在您的示例中,当算法在遇到第一个循环之前必须遍历太多顶点时,就会发生这种情况。 (“太多”这里可能意味着“几千”,并且取决于最大堆栈大小,以及每个堆栈所需的内存量)。

您可以考虑将方法从递归转换为迭代。这可能只是一个广度或深度优先搜索。

我试图在这里实现这一点,但结构(指VVertex<V>vertexMap等的角色)非常令人困惑,所以我并不完全确定这是正确的:

public boolean isInCycle(V vertex) throws IllegalArgumentException
{
    if (!hasVertex(vertex))
    {
        throw new IllegalArgumentException();
    }
    Iterator<Vertex<V>> v = vertexMap.keySet().iterator();
    while (v.hasNext())
    {
        Vertex<V> vert = v.next();
        vert.activated = false;
        vert.through = false;
    }

    Deque<V> queue = new LinkedList<V>();
    queue.add(vertex);
    vertexMap.get(new Vertex<V>(vertex)).vertex().activated = true;
    while (!queue.isEmpty())
    {
        V current = queue.removeFirst();
        Iterator<V> neighbors = getNeighbors(current).iterator();
        while (neighbors.hasNext())
        {
            V neighbor = neighbors.next();
            Vertex<V> n = vertexMap.get(new Vertex<V>(neighbor)).vertex();
            if (n.activated)
            {
                return true;
            }
            else
            {
                queue.add(neighbor);
                n.activated = true;
            }
        }
    }
    return false;
}