Created
March 2, 2017 03:29
-
-
Save codingmiao/f02f14c4c52a5195f18fb0bc37d70635 to your computer and use it in GitHub Desktop.
寻找图中两个点间所有可达路径
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package switchtest; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.Stack; | |
/** | |
* 寻找图中两个点间所有可达路径 | |
*/ | |
public class RouteSearch { | |
/* 临时保存路径节点的栈 */ | |
private final Stack<Node> stack = new Stack<>(); | |
/* 存储路径的集合 */ | |
private final ArrayList<Node[]> routes = new ArrayList<>(); | |
/* 判断节点是否在栈中 */ | |
private boolean isNodeInStack(Node node) { | |
Iterator<Node> it = stack.iterator(); | |
while (it.hasNext()) { | |
Node node1 = it.next(); | |
if (node == node1) | |
return true; | |
} | |
return false; | |
} | |
/* 此时栈中的节点组成一条所求路径,转储并打印输出 */ | |
private void saveRoute() { | |
Node[] ns = new Node[stack.size()]; | |
stack.toArray(ns); | |
routes.add(ns); | |
} | |
/** | |
* 需找两个node间所有路径 | |
* | |
* @param beginNode 起点 | |
* @param endNode 终点 | |
* @return list list中的一个数组表示一条路径,数组中元素顺序地表示从起点(含)到终点(含)所经过的节点 | |
*/ | |
public ArrayList<Node[]> searchRoutes(Node beginNode, Node endNode) { | |
getPaths(beginNode, null, beginNode, endNode); | |
return routes; | |
} | |
/* | |
* 寻找路径的方法 | |
* cNode: 当前的起始节点currentNode | |
* pNode: 当前起始节点的上一节点previousNode | |
* sNode: 最初的起始节点startNode | |
* eNode: 终点endNode | |
*/ | |
private boolean getPaths(Node cNode, Node pNode, Node sNode, Node eNode) { | |
Node nNode; | |
/* 如果符合条件判断说明出现环路,不能再顺着该路径继续寻路,返回false */ | |
if (cNode != null && pNode != null && cNode == pNode) | |
return false; | |
if (cNode != null) { | |
int i = 0; | |
/* 起始节点入栈 */ | |
stack.push(cNode); | |
/* 如果该起始节点就是终点,说明找到一条路径 */ | |
if (cNode == eNode) { | |
/* 转储并打印输出该路径,返回true */ | |
saveRoute(); | |
return true; | |
} | |
/* 如果不是,继续寻路 */ | |
else { | |
/* | |
* 从与当前起始节点cNode有连接关系的节点集中按顺序遍历得到一个节点 | |
* 作为下一次递归寻路时的起始节点 | |
*/ | |
nNode = cNode.getRelationNodes().get(i); | |
while (nNode != null) { | |
/* | |
* 如果nNode是最初的起始节点或者nNode就是cNode的上一节点或者nNode已经在栈中 , | |
* 说明产生环路 ,应重新在与当前起始节点有连接关系的节点集中寻找nNode | |
*/ | |
if (pNode != null | |
&& (nNode == sNode || nNode == pNode || isNodeInStack(nNode))) { | |
i++; | |
if (i >= cNode.getRelationNodes().size()) | |
nNode = null; | |
else | |
nNode = cNode.getRelationNodes().get(i); | |
continue; | |
} | |
/* 以nNode为新的起始节点,当前起始节点cNode为上一节点,递归调用寻路方法 */ | |
if (getPaths(nNode, cNode, sNode, eNode))/* 递归调用 */ { | |
/* 如果找到一条路径,则弹出栈顶节点 */ | |
stack.pop(); | |
} | |
/* 继续在与cNode有连接关系的节点集中测试nNode */ | |
i++; | |
if (i >= cNode.getRelationNodes().size()) | |
nNode = null; | |
else | |
nNode = cNode.getRelationNodes().get(i); | |
} | |
/* | |
* 当遍历完所有与cNode有连接关系的节点后, | |
* 说明在以cNode为起始节点到终点的路径已经全部找到 | |
*/ | |
stack.pop(); | |
return false; | |
} | |
} else | |
return false; | |
} | |
public static void main(String[] args) { | |
/* 定义节点关系 */ | |
int nodeRalation[][] = | |
{ | |
{1}, //0 | |
{0, 5, 2, 3},//1 | |
{1, 4}, //2 | |
{1, 4}, //3 | |
{2, 3, 5}, //4 | |
{1, 4} //5 | |
}; | |
/* 定义节点数组 */ | |
Node[] node = new Node[nodeRalation.length]; | |
for (int i = 0; i < nodeRalation.length; i++) { | |
node[i] = new Node(); | |
node[i].setName("node" + i); | |
} | |
/* 定义与节点相关联的节点集合 */ | |
for (int i = 0; i < nodeRalation.length; i++) { | |
ArrayList<Node> List = new ArrayList<Node>(); | |
for (int j = 0; j < nodeRalation[i].length; j++) { | |
List.add(node[nodeRalation[i][j]]); | |
} | |
node[i].setRelationNodes(List); | |
} | |
/* 开始搜索所有路径 */ | |
RouteSearch s = new RouteSearch(); | |
ArrayList<Node[]> routes = s.searchRoutes(node[0], node[4]); | |
StringBuilder sb = new StringBuilder(); | |
for (Node[] route : routes) { | |
for (Node n : route) { | |
sb.append(n.getName()).append("->"); | |
} | |
sb.append("end\n"); | |
} | |
System.out.println(sb.toString()); | |
} | |
} | |
class Node { | |
public String name = null; | |
public ArrayList<Node> relationNodes = new ArrayList<>(); | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public ArrayList<Node> getRelationNodes() { | |
return relationNodes; | |
} | |
public void setRelationNodes(ArrayList<Node> relationNodes) { | |
this.relationNodes = relationNodes; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment