求图中某点到另一点的通路
图的搜索方法有DFS和BFS,但是这两个算法不能直接得到(其实是我不会)图中任意一点到另外一点的通路路径,以图中某个点作为起点,另外一点作为终点,从终点开始,利用邻接表,从后向前查找,首先查找可以直接到终点的节点,放入集合S1中,然后再查找可以直接到S1的节点,存入集合S2,只到找到起点为止。代码如下:
1 public static void getReachableNodeCollection(){ 2 ArrayList<ArrayList<Integer>> reachableNodeCollection=new ArrayList<ArrayList<Integer>>(); 3 ArrayList<Integer> reachableNode=new ArrayList<>(); 4 ArrayList<Integer> tempNeighbour; 5 final ArrayList<Integer> keySet=new ArrayList<>(); 6 for (Integer key:neighbourTable.keySet()){ 7 if (!key.equals(demandRouterArray[1])) 8 { 9 keySet.add(key); 10 } 11 } 12 Integer key; 13 tempNeighbour=new ArrayList<>(); 14 for (int i = 0; i < keySet.size(); i++) { 15 key=keySet.get(i); 16 tempNeighbour.addAll(neighbourTable.get(key)); 17 if ((tempNeighbour.contains(demandRouterArray[1]))){ 18 reachableNode.add(key); 19 //continue; 20 21 } 22 tempNeighbour.clear(); 23 24 } 25 reachableNodeCollection.add(new ArrayList<Integer>(reachableNode));//到最后一个节点的节点集合存在第一个位置,将来获得路径是要逆序访问 26 ArrayList<Integer> copyOfReachableNode; 27 ArrayList<Integer> currentKeySet=new ArrayList<>(keySet); 28 currentKeySet.removeAll(reachableNode); 29 Integer NodeId; 30 copyOfReachableNode=new ArrayList<>(); 31 boolean findStartNode=false; 32 Integer startNodeId=demandRouterArray[0]; 33 while(currentKeySet.size()>0&&!reachableNode.contains(startNodeId)){ 34 copyOfReachableNode.addAll(reachableNode); 35 reachableNode.clear(); 36 for (int i = 0; i <currentKeySet.size() ; i++) { 37 key=currentKeySet.get(i); 38 39 tempNeighbour.addAll(neighbourTable.get(key)); 40 for (int j = 0; j <copyOfReachableNode.size() ; j++) { 41 NodeId=copyOfReachableNode.get(j); 42 if (tempNeighbour.contains(NodeId)){ 43 reachableNode.add(key); 44 if (key.equals(startNodeId)){ 45 findStartNode=true;//如果已经找到起始点,就跳出搜索 46 } 47 break; 48 } 49 } 50 tempNeighbour.clear(); 51 if (findStartNode){ 52 break; 53 } 54 } 55 reachableNodeCollection.add(new ArrayList<Integer>(reachableNode)); 56 currentKeySet.removeAll(reachableNode); 57 copyOfReachableNode.clear(); 58 if (findStartNode){ 59 break; 60 } 61 } 62 System.out.println(); 63 }
其中,从后向前查找时,首先查找到的节点ID存储在reachableNodeCollection中,如下:
reachableNodeCollection.add(new ArrayList<Integer>(reachableNode));
由于之后要将reachableNode使用clear()方法清空,所以这里需要使用new创建一个新的ArrayList对象,在新的空间中拷贝了一份reachableNode中的引用,这些引用指向一些Integer对象。如果不是有new创建新对象,而是直接使用如下形式的话
reachableNodeCollection.add(reachableNode));
这里只是将reachableNode的地址添加进来,当reachableNode.clear()之后,reachableNode中的引用被清空,reachNodeCollection自然也找不到原先的Integer内容了。