对于一个学校项目,他们要求我们制作dijkstra的算法。我有类:Node,Edge,graph和Dijkstra使用graph.getNodes(返回一个List)并在使用find path graph.getnodes后将它存储在findPath(在djikstra中)的局部变量中返回一个大小为5的列表而不是getNodes来自graph.java,findPath来自Djikstra.java
public List<Node> getNodes() {
return nodes;
}
public void findPath (Node s, Node d) {
System.out.println("nodeSize at begining of findpath : "+graph.getNodes().size());
List<Node> nodes = graph.getNodes();
dijkstraTable = new Map[nodes.size()];
//verify paramaters
if(!nodes.contains(s)) throw new InvalidParameterException("the source node is not valid");
if(!nodes.contains(d)) throw new InvalidParameterException("the destination node is not valid");
if(s == null || d == null ) throw new NullPointerException("s or d are null");
Edge edge0 = new Edge(s,s,0);
Map<Node,Edge> map = new HashMap<Node,Edge>();
map.put(s, edge0);
int i =0;
dijkstraTable[i] = map;
//iteration > 0
while(!nodes.isEmpty()) {
i++;
if (i==nodes.size()) break;
Map<Node,Edge> newMap = new HashMap<Node,Edge>();
map = dijkstraTable[i-1]; //last iteration map
//get minimum last iteration
Node min = getMinimum(map);
//mark it as "visited"
nodes.remove(min);
//add it to the path
List<Edge> edges = graph.getEdgesGoingFrom(min);
System.out.println("nodeSize in loop: "+graph.getNodes().size());
for(Edge edge : edges) {
Node key = edge.getDestination();
if(!map.containsKey(key)) { //create it if doesnt exist
newMap.put(key, edge);
}else { //make sure to have the minimum value
if(getMinimum(map.get(key), edge) == edge) newMap.put(key, edge);
else newMap.put(key, map.get(key));
}
}//endfor
path.add(map.get(min));
dijkstraTable[i] = newMap;
}
System.out.println("nodeSize at end of findpath : "+graph.getNodes().size());
}
输出是
findpath开头的nodeSize:7
nodeSize in loop:6
nodeSize in loop:5
nodeSize in loop:5
nodeSize in loop:5
findpath末尾的nodeSize:5
每次都应该是7
你的问题在这里:
public List<Node> getNodes() {
return nodes;
}
...
List<Node> nodes = graph.getNodes();
您正在使用findPath
方法修改“私人”列表。如果你想避免修改,可以使用Collections.unmodifiableList(nodes)
int getNodes()
or在findPath
中创建一个新列表并将graph.getNodes()
传递给列表构造函数。
更改
List<Node> nodes = graph.getNodes();
至
List<Node> nodes = new ArrayList<>(graph.getNodes());
这将在findPath方法中创建列表的本地副本。
或者你可以改变
public List<Node> getNodes() {
return nodes;
}
至
public List<Node> getNodes() {
return new ArrayList<>(nodes);
}
这将在getNodes()方法中返回列表的副本。