原文:
Given a directed graph, design an algorithm to find out whether there is a route between two nodes.
译文:
给定一个有向图,设计算法判断两结点间是否存在路径。
根据题意,给定一个有向图和起点终点,判断从起点开始,是否存在一条路径可以到达终点。 考查的就是图的遍历,从起点开始遍历该图,如果能访问到终点, 则说明起点与终点间存在路径。稍微修改一下遍历算法即可。
package chapter_4_TreesandGraphs;
import java.util.Scanner;
/**
* 边集
*/
class ArcNode{
public int data;
public ArcNode next;
public ArcNode(int data) {
this.data = data;
this.next = null;
}
public void printArcNode() {
System.out.format(" %d -->", data);
}
}
/**
* 顶点集
*/
class VexNode {
public int data;
public ArcNode first;
public VexNode(int data) {
this.first = null;
this.data = data;
}
public void addArc(int arcdata) {
ArcNode p = null;
ArcNode arcNode = new ArcNode(arcdata);
if(first == null) {
first = arcNode;
} else {
p = first;
first = arcNode;
arcNode.next = p;
}
}
public void printVexNode() {
System.out.format("顶点 %d :", data);
ArcNode arcNode = first;
while(arcNode != null) {
if(arcNode.next != null) {
arcNode.printArcNode();
} else {
System.out.format(" %d ", arcNode.data);
}
arcNode = arcNode.next;
}
System.out.format("\n");
}
}
/**
* 有向图
*/
class Graph {
public int vexNum; // 顶点数目
public int arcNum; // 边数目
public VexNode[] adj;
public boolean visited[];
public Graph(int vexNum) {
this.vexNum = vexNum;
this.arcNum = 0;
adj = new VexNode[vexNum];
}
public void addNode(int node) {
for(int i=0; i<vexNum; i++) {
if(adj[i] == null) {
adj[i] = new VexNode(node);
return;
}
}
}
public void addArc(int start, int end) {
for(int i=0; i<vexNum; i++) {
if(adj[i].data == start) {
adj[i].addArc(end);
return;
}
}
System.out.format("顶点 %d 不存在该结点信息!\n", start);
}
public void printGraph() {
for(int i=0; i<vexNum; i++) {
if(adj[i] == null) {
return;
}
adj[i].printVexNode();
}
}
public void DFSTraverse() {
visited = new boolean[vexNum];
for(boolean tem:visited) {
tem = false;
}
for(int i=0; i<vexNum; i++) {
if(visited[i] == false) {
DFS(i);
}
}
}
public void DFS(int i) {
visit(i);
visited[i] = true;
ArcNode arcNode = adj[i].first;
while(arcNode != null) {
int index = findIndex(arcNode.data);
if(visited[index] == false) {
DFS(index);
}
arcNode = arcNode.next;
}
}
/**
* 默认从第一个结点出发的广度遍历算法
*/
public void BFSTraverse() {
boolean visited[] = new boolean[vexNum];
for(boolean tem: visited) {
tem = false;
}
for(int i=0; i<vexNum; i++) {
if(visited[i] == false) {
visit(i);
visited[i] = true;
int queue[] = new int[vexNum];
int head = 0;
int tail = 0;
queue[tail++] = adj[i].data;
while(head < tail) {
int cur = queue[head++];
ArcNode arcNode = adj[i].first;
while(arcNode != null) {
int index = findIndex(arcNode.data);
if(visited[index] == false) {
visit(index);
visited[index] = true;
queue[tail++] = index;
}
arcNode = arcNode.next;
}
}
}
}
}
public void visit(int i) {
System.out.print(" " + adj[i].data);
}
public int findIndex(int value) {
int index = -1;
for(int i=0; i<vexNum; i++) {
if(adj[i].data == value) {
index = i;
break;
}
}
return index;
}
public boolean route(int m, int n) {
boolean visited[] = new boolean[vexNum];
for(boolean tem: visited) {
tem = false;
}
int index = findIndex(m);
int[] queue = new int[vexNum];
int head = 0;
int tail = 0;
queue[tail++] = index;
while(head < tail) {
int cur = queue[head++];
visited[cur] = true;
if(adj[cur].data == n) {
return true;
}
ArcNode arcNode = adj[cur].first;
while(arcNode != null) {
index = findIndex(arcNode.data);
if(visited[index] == false) {
if(arcNode.data == n) {
return true;
}
queue[tail++] = index;
}
arcNode = arcNode.next;
}
}
return false;
}
}
/**
*
* 给定一个有向图,设计算法判断两结点间是否存在路径。
*
*/
public class Question_4_2 {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int arcnum = scanner.nextInt();
scanner.nextLine();
Graph graph = new Graph(arcnum);
String nodeString = scanner.nextLine();
String nodes[] = nodeString.split(" ");
for(int i=0; i<nodes.length; i++) {
graph.addNode(Integer.parseInt(nodes[i]));
}
while(true) {
int start = scanner.nextInt();
int end = scanner.nextInt();
scanner.nextLine();
if(start == 0 && end ==0) {
break;
}
graph.addArc(start, end);
}
graph.printGraph();
System.out.println("广度遍历 :");
graph.BFSTraverse();
System.out.println("\n深度遍历 :");
graph.DFSTraverse();
System.out.println("\n输入需要检验的两个结点 :");
int m = scanner.nextInt();
int n = scanner.nextInt();
boolean result = graph.route(m, n);
if(result) {
System.out.format("%d %d 存在路径", m,n );
} else {
System.out.format("%d %d 不存在路径", m,n );
}
}
}