Java 邻接矩阵的简单加法函数
我正在开发一个邻接矩阵,以便我可以尝试使用DFS来解决euler回路问题。 这是我问题的相关代码:Java 邻接矩阵的简单加法函数,java,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;
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());
}
publicstaticvoidmain(字符串[]args){
扫描仪输入=新扫描仪(System.in);
int numVertices=input.nextInt();
int numLinks=input.nextInt();
int startNode=input.nextInt();
图g=新图(num属性、numLinks);
对于(inti=0;i记住,你的矩阵是以零为基的
如果将4作为数值传递,则矩阵将从0,0变为3,3
然后,如果您尝试在顶点4和任何其他顶点之间添加边,您将出现错误…请记住,您的矩阵是以零为基础的
如果将4作为数值传递,则矩阵将从0,0变为3,3
然后,如果您尝试在顶点4和任何其他顶点之间添加边,则会出现错误…当您增加边数时,adj
矩阵的大小不会自动更改。当您增长图形时,需要重新分配矩阵并将旧值复制到新矩阵。您可以通过首先分配一个更大的矩阵(因此大小和容量之间存在差异),只有在容量不足时才重新分配
我建议您,因为您只是存储布尔值,而不是二维矩阵,所以只需使用位集
(实际上是位向量,而不是集)。您可以使用以下方法将(行、列)对转换为线性数组索引:
index = row * numEdges + column;
如果需要,您可以选择另一种方式:
当图形增长时,仍然需要重新分配位集
,但这样可以节省大量存储空间
编辑
再想一想,我认为问题在于您没有检查顶点数是否在范围内。如果您希望用户指定从1开始的顶点数,则需要从用户输入中减去1,以便adj
的索引从0开始。至少,您应该检查端点输入是否有效
如果您想尝试,则位集
实现如下所示:
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++;
}
}
由于邻接矩阵是对称的,因此只存储上(或下)邻接矩阵可以节省更多的存储空间三角形部分。但这会使索引计算更复杂。当您增加边数时,adj
矩阵的大小不会自动更改。当您增长图形时,您需要重新分配矩阵并将旧值复制到新矩阵。您可以通过alloc保存重新分配一开始需要一个更大的矩阵(因此大小和容量之间存在差异),只有在容量用完时才进行重新分配
我建议您,因为您只是存储布尔值,而不是二维矩阵,所以只需使用位集
(实际上是位向量,而不是集)。您可以使用以下方法将(行、列)对转换为线性数组索引:
index = row * numEdges + column;
如果需要,您可以选择另一种方式:
当图形增长时,仍然需要重新分配位集
,但这样可以节省大量存储空间
编辑
再想一想,我认为问题在于您没有检查顶点数是否在范围内。如果您希望用户指定从1开始的顶点数,则需要从用户输入中减去1,以便adj
的索引从0开始。至少,您应该检查端点输入是否有效
如果您想尝试,则位集
实现如下所示:
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++;
}
}
由于邻接矩阵是对称的,因此只存储上(或下)邻接矩阵可以节省更多的存储空间三角形部分。但这会使索引计算变得有点复杂。嗨,泰德,我不明白……你建议我更改现有的实现,或者这是对现有实现的可能更正?使用位集会是什么样子?@CláudioRibeiro-我想我在第一次回答中遗漏了一些东西。我已经编辑了我的答案,还提供了一些使用位集的示例代码。嗨,泰德,我不明白……你建议我更改我已有的实现,或者这是对我已有的实现的可能更正?使用位集会是什么样子?@CláudioRibeiro-我想我在第一次回答中遗漏了一些东西。我编辑了my回答,并提供了一些使用位集
的示例代码。