图学习笔记索引
图学习笔记索引(全部)
001自定义输入流In类实现
002背包数据类型Bag实现
003无向图数据类型实现
004基于图的深度优先搜索
005使用深度优先搜索找图中的所有连通分量
005-1基于深度优先搜索查找图中连通路径
006基于深度优先搜索判断图中是否存在环
007基于深度优先搜索判断一个无向图图是否是一个二分图
008广度优先搜索查找连通图中的最短路径
009有向图数据类型实现
010有向图的可达性
011带权重的无向边数据类型Edge实现
012加权无向图数据类型实现
本文参考《算法(第4版)》
基于图的深度优先搜索
1.自定义输入流In
从文件中读取无向图图的顶点关系。
tinyWG.txt文件中的第一行为顶点数,第二行为边数。
第三行到最后是两个相邻的顶点:
13
13
0 5
4 3
0 1
9 12
6 4
5 4
0 2
11 12
9 10
0 6
7 8
9 11
5 3
点击文字获取:001自定义输入流In类实现
2.定义背包类Bag
点击文字获取:002背包数据类型Bag实现
3.无向图G的构造
从文件中读取图的顶点信息,构造一幅无向图。
点击文字获取:003无向图数据类型实现
4.深度优先搜索DepthFirstSearch
点击文字获取:004基于图的深度优先搜索
5.使用深度优先搜索查找连通路径DepthFirstPaths
package algorithms.graph;
import java.io.IOException;
import java.util.Stack;
/*
* 使用深度优先搜索查找连通分量路径;
* */
public class DepthFirstPaths {
private boolean[] marked;
private int[] edgeTo;
private final int s;
DepthFirstPaths(Graph G, int s){
marked = new boolean[G.V()];
edgeTo = new int[G.V()];
this.s = s;
dfs(G, s);
}
public void dfs(Graph G, int v){
marked[v] = true;
for(int w : G.adj(v))
if(!marked[w]){
edgeTo[w] = v;
dfs(G, w);
}
}
public boolean hasPathTo(int w){
return marked[w];
}
// public Iterable<Integer> pathTo(int v){
// if(!hasPathTo(v)) return null;
// Stack<Integer> path = new Stack<Integer>();
// for(int x = v; x != s; x = edgeTo[x])
// path.push(x);
// path.push(s);
// return path;
// }
//起点s到顶点v的路径
public Stack<Integer> pathTo(int v){
if(!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
for(int x = v; x != s; x = edgeTo[x])
path.push(x);
path.push(s);
return path;
}
public static void main(String[] args) throws IOException {
//测试用例
In in = new In("D:\\tinyWG.txt");
Graph G = new Graph(in);
int s = 0;
DepthFirstPaths search = new DepthFirstPaths(G, s);
Stack<Integer> stack = new Stack<Integer>();
System.out.println("测试迭代器输出顺序:");
for(int x : search.pathTo(5))
System.out.print(x+"-");
System.out.println();
System.out.println("测试stack输出顺序:");
//格式化输出
for(int v = 0; v < G.V(); v++){
System.out.print(s + " to " + v + " path: ");
if(search.hasPathTo(v)){
stack = search.pathTo(v);
while(stack!=null&&!stack.isEmpty()){
int x = stack.pop();
if( x == s)
System.out.print(x);
else System.out.print("-"+x);
}
}
System.out.println();
}
//反向路径
System.out.println();
System.out.println("测试Queue迭代器输出顺序:");
for(int v = 0; v < G.V(); v++){
System.out.print(v + " to " + s + " path is : ");
if(search.hasPathTo(v)){
for(int x : search.pathTo(v))
if( x == s) System.out.print(x);
else System.out.print(x + "-");
}
System.out.println();
}
}
}
6.总结
使用基于深度优先搜索查找图中连通路径,其思想是使用一个edgeTo[]数组来保存每个顶点的上一个连接节顶点,即当前顶点索引前一个顶点。使用Stack这种数据结构保存当前顶点到起始顶点的所有顶点。从起始顶点出发连接所有顶点会构成一个以起始顶点为根顶点的顶点树。