查找加权有向图中两个指定顶点之间是否存在任何路径

时间:2017-03-28 01:05:38

标签: java algorithm data-structures graph

我正在尝试实现一个方法isReachable(E fromKey, E toKey)来确定图中两个指定顶点之间是否存在任何路径。我有一个泛型类Graph<E>,它使用两个内部数据结构VertexEdge来表示图的顶点和边。这是代码:

public class Graph<E extends Comparable<E>> implements GraphAPI<E>
{
    /*
     * number of vertices (size of this graph)
     */
    private long order;
    /**
     * pointer to the list of vertices
     */
    private Vertex first;

    /**
     * A vertex of a graph stores a data item and references
     * to its edge list and the succeeding vertex. The data
     * object extends the comparable interface.
     */
    private class Vertex
    {
        /**
         * pointer to the next vertex
         */
        public Vertex pNextVertex;
        /**
         * the data item
         */
        public E data;
        /**
         * indegree
         */
        public long inDeg;
        /**
         * outdegree
         */
        public long outDeg;
        /**
         * pointer to the edge list
         */
        public Edge pEdge;
        /**
         * Field for tracking vertex accesses
         */
        public long processed;
    }

    /**
     * An edge of a graph contains a reference to the destination
     * vertex, a reference to the succeeding edge in the edge list and
     * the weight of the directed edge.
     */
    private class Edge
    {
        /**
         * pointer to the destination vertex
         */
        public Vertex destination;
        /**
         * weight on this edge
         */
        public Double weight;
        /**
         * pointer to the next edge
         */
        public Edge pNextEdge;
    }
    /**
     * Constructs an empty weighted directed graph
     */
    public Graph()
    {
        first = null;
        order = 0;
    }
}

这是我的思考过程: (1)遍历顶点列表,直到到达包含指定fromKey的顶点; (2)将每个相邻的顶点添加到fromKey到队列; (3)当队列不为空时,检索并删除队列头部的顶点,并将其与toKey的关键字进行比较; (4)如果匹配返回true,则继续搜索每个相邻Vertex的边列表。

这是我到目前为止的方法代码:

/**
 * Determines whether there is an outdirected path between two
 * vertices.
 * @param fromKey - search key of the originating vertex.
 * @param toKey - search key of the destination vertex.
 * @return true on success or false on failure.
 */
public boolean isReachable(E fromKey, E toKey)
{
    ArrayList<Vertex> queue = new ArrayList<Vertex>();
    E tmpKey = fromKey;
    Edge tmpEdge;
    Vertex tmp = first;
    while (tmp != null)
    {
        if (tmp.data.equals(tmpKey))
        {
            tmpEdge = tmp.pEdge;
            while (tmpEdge != null)
            {
                queue.add(tmpEdge.destination);
                tmpEdge = tmpEdge.pNextEdge;
            }
            tmp = first;
            tmpKey = queue.remove(0).data;
            if (tmpKey.equals(toKey))
                return true;
        }
        tmp = tmp.pNextVertex;
    }
    return false;
}

当存在两个指定键之间的路径时,它会起作用,但是当没有时,会抛出索引超出范围的错误。

这是我跟踪的样本数据的邻接列表:

1  -> null
2  -> 1 -> 11 -> 12 -> null
3  -> 2 -> 4 -> null
4  -> null
5  -> 4 -> null
6  -> 5 -> 7 -> 13 -> 14 -> 15 -> null
7  -> 12 -> null
8  -> 7 -> 9 -> 10 -> 11 -> 12 -> null
9  -> 1 -> null
10 -> null
11 -> 1 -> 12 -> null
12 -> null
13 -> null
14 -> 2 -> 3 -> null
15 -> 3 -> 5 -> 14 -> null

例如,当我调用isReachable(5, 3)时,我得到一个超出范围的索引异常。但如果我在(15,2)上调用该方法,则返回true。

我不确定从哪里开始。一位朋友建议尝试采用BFS方法解决问题,但我并没有真正按照他的解释。我是在正确的轨道上吗?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

这是一个基本的图搜索算法,google&#34;广度优先搜索&#34;作为一个起点。您需要跟踪您访问过的节点,我们还没有看到您已经完成的节点。

另外,正如我在评论中所说,不要使用ArrayList来维护队列,remove操作很慢,特别是删除数组开头的元素您必须复制所有内容1.直接使用Queuehttps://docs.oracle.com/javase/7/docs/api/java/util/Queue.html