在DrJava中读取文本文件生成邻接表:我的代码存在哪些问题?
你的代码存在的问题及修正方案
先来看你输入文件的格式:所有数据是单行的(5 6 1,2 2,4 3,5 1,2 2,4 3,5),但你的代码逻辑完全是按多行读取设计的,这是核心问题之一。下面逐一拆解错误:
主要错误点
- 输入读取逻辑错误:
你用s.nextLine()分别读取节点数和边数,但实际上所有输入都在同一行里。这会导致第一次line = s.nextLine()就读取了全部内容,后续的s.nextLine()会直接抛出NoSuchElementException,因为没有更多行了。 - 嵌套循环逻辑彻底混乱:
内层的for(int i = 0; line != null; i++, line = s.nextLine())条件和循环体完全不匹配,而且每次循环都调用s.nextLine()会跳过大量输入;最内层的for(int j = 0; line == s.nextLine();j++)更是逻辑错误——line == s.nextLine()是比较字符串对象的引用,而且每次判断都会读取新的一行,完全偏离了处理每条边的需求。 - 邻接表初始化缺失:
邻接表需要先为每个节点初始化一个空的ArrayList,比如节点数是5,就需要先给list添加5个空列表。你的代码是每次处理边就添加新列表,这会导致邻接表的结构完全错误。 - 错误输出
add方法的返回值:list.get(i).add(...)返回的是boolean类型(表示是否添加成功),你直接打印这个值会输出true/false,而不是你想要的节点编号。 - 边处理逻辑错误:
每条边是u,v格式,你需要把v加入u的邻接列表(如果是无向图,还要把u加入v的邻接列表),但你的代码没有正确关联节点和它的邻接节点。
修正后的代码
下面是修复后的代码,完全适配你的输入格式,能正确生成邻接表并输出:
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Scanner; public class JavaApplication1 { public static void main(String[] args) throws FileNotFoundException { // 初始化邻接表 ArrayList<ArrayList<Integer>> adjacencyList = new ArrayList<>(); File f = new File("D:\\Documents\\Study\\Spring '18\\CSE221\\FSI\\CSE221\\Labs\\Lab01\\AdjacencyList\\input.txt"); Scanner s = new Scanner(f); // 读取整行输入,按空格分割成所有元素 String[] allElements = s.nextLine().split(" "); // 解析节点数和边数 int noOfNode = Integer.parseInt(allElements[0]); int noOfEdge = Integer.parseInt(allElements[1]); // 初始化每个节点的空邻接列表 for (int i = 0; i < noOfNode; i++) { adjacencyList.add(new ArrayList<>()); } // 处理每条边(从第3个元素开始,索引2) for (int i = 2; i < allElements.length; i++) { String[] edge = allElements[i].split(","); int u = Integer.parseInt(edge[0]) - 1; // 注意:如果节点是1-based,转成0-based索引 int v = Integer.parseInt(edge[1]) - 1; // 无向图:双向添加邻接关系 adjacencyList.get(u).add(v + 1); // 存回1-based的节点编号 adjacencyList.get(v).add(u + 1); } // 打印邻接表 System.out.println("邻接表输出:"); for (int i = 0; i < adjacencyList.size(); i++) { System.out.print("节点 " + (i + 1) + " 的邻接节点:"); for (int node : adjacencyList.get(i)) { System.out.print(node + " "); } System.out.println(); } s.close(); } }
代码说明
- 输入处理:一次性读取整行输入,按空格分割成所有元素,这样就能正确获取节点数、边数和所有边数据。
- 邻接表初始化:先为每个节点创建空列表,保证邻接表的结构正确。
- 边处理:把1-based的节点编号转成0-based的索引(因为Java集合是0-based),处理完后存回1-based编号方便阅读。如果你的图是有向图,只需要添加单向的邻接关系即可。
- 输出优化:清晰打印每个节点的邻接节点,符合邻接表的展示需求。
内容的提问来源于stack exchange,提问作者Ashfaq
相关产品推荐
相关产品推荐

