简单地向邻接矩阵添加函数

时间:2012-03-22 00:54:52

标签: java

我正在开发一个邻接矩阵,所以我可以尝试使用DFS来解决euler电路问题。 这是我的问题的相关代码:

public class Graph {

private int numVertex;
private int numEdges;
private boolean[][] adj;

public Graph(int numVertex, int numEdges) {
    this.numVertex = numVertex;
    this.numEdges = numEdges;
    this.adj = new boolean[numVertex][numVertex];
}

public void addEdge(int start, int end){
    if(!adj[start][end])
        numEdges++;
    adj[start][end] = true;
    adj[end][start] = true;
}

当我尝试通过添加一些边缘来测试运行此代码时,我得到:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Graph.addEdge(Graph.java:18)
at Graph.main(Graph.java:66)

我正在使用它来测试代码:

    public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    int numVertices = input.nextInt();
    int numLinks = input.nextInt();
    int startNode = input.nextInt();

    Graph g = new Graph(numVertices, numLinks);

    for(int i = 0; i<numLinks; i++){
        g.addEdge(input.nextInt(),input.nextInt());
    }

我认为问题出在addEdge函数中。我做错了什么?

2 个答案:

答案 0 :(得分:2)

请记住,您的矩阵是从零开始的。

如果您将4作为numVertices传递,则矩阵将从0,0变为3,3。

然后,如果您尝试在顶点4和任何其他顶点之间添加边缘,则会出现错误...

答案 1 :(得分:2)

当您增加边数时,adj矩阵的大小不会自动更改。增长图形时,需要重新分配矩阵并将旧值复制到新矩阵。您可以通过分配一个更大的矩阵来开始(因此大小和容量之间存在差异)并且仅在容量耗尽时重新分配,从而节省重新分配。

我可以建议,因为你只是存储一个布尔值,而不是二维矩阵,你只需要使用BitSet(它实际上是一个位向量,而不是一个集合)。您可以使用以下方法将(行,列)对转换为线性数组索引:

index = row * numEdges + column;

你可以用另一种方式(如果需要)用:

column = index % numEdges;
row = index / numEdges;

当图表增长时,您仍需要重新分配BitSet,但您将节省大量存储空间。

修改

第二个想法,我认为问题是你没有检查顶点数是否在范围内。如果希望用户指定从1开始的顶点数,则需要从用户输入中减去1,以便adj的索引从0开始。至少应检查端点输入是否有效

如果你想尝试一下,BitSet实现看起来像这样:

public class Graph {

private int numVertex;
private int numEdges;
private BitSet adj;

public Graph(int numVertex, int numEdges) {
    this.numVertex = numVertex;
    this.numEdges = numEdges;
    this.adj = new BitSet(numVertex * numVertex);
}

public void addEdge(int start, int end){
    int index = start * numVertex + end;
    if (!adj.get(index)) {
        adj.set(index);
        index = end * numVertex + start;
        adj.set(index);
        numEdges++;
    }
}

由于邻接矩阵是对称的,因此只需存储上(或下)三角形部分即可节省更多存储空间。但这会使索引计算变得更复杂。