2-1 图的两种形式遍历
所谓图的遍历(_graph traversal_),也称为搜索(_search_),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使
每个顶点仅被访问一次。遍历可以采取两种方法进行:深度优先搜索(DFS,_depth first search_)
和广度优先搜索(BFS,_breadth first search_)。
2-2 图的深度优先遍历伪代码
深度优先搜索是一个递归过程,有回退过程。DFS 算法的思想是:对一个无向连通图,在访问图中某一起始顶点 v 后,由 v 出、
发,访问它的某一邻接顶点 _w_1;再从 _w_1出发,访问与 _w_1邻接但还没有访问过的顶点 _w_2;然后再从 _w_2出发,进行类似的访
问;…;如此进行下去,直至到达所有邻接顶点都被访问过的顶点 u 为止;接着,回退一步,回退到前一次刚访问过的顶点,看
是否还有其它没有被访问过的邻接顶点,如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就
再回退一步进行类似的访问。重复上述过程,直到该连通图中所有顶点都被访问过为止。
树的前序遍历,与图的深度优先遍历的比较:
2-3 DFS逻辑的微观解读,深度优先遍历顺序
深度优先遍历的递归的遍历形式:
2-4 实现图的深度优先遍历
连通图的深度优先遍历
-结合上述的伪代码
package graphDFS;
import java.util.ArrayList;
public class GraphDFS {
// 创建一个数组,
private ArrayList<Integer> res = new ArrayList<>(); // 输出最后深度优先遍历的结果
private boolean[] visited;
private Graph graph;
public GraphDFS(Graph graph) {
this.graph = graph;
visited = new boolean[graph.V()]; // 结点的数量
dfs(0);
}
private void dfs(int v) {
visited[v] = true;
res.add(v);
for (int w: graph.adj(v)) { // 遍历该节点的相邻结点
if (! visited[w])
dfs(w);
}
}
public Iterable<Integer> res(){
return res;
}
public static void main(String[] args) {
Graph graph = new Graph("g2.txt");
GraphDFS graphDFS = new GraphDFS(graph);
System.out.println(graphDFS.res());
// [0, 1, 3, 2, 6, 5, 4]
}
}
2-5 图的深度优先遍历的改进
如果不是联通图的话,孤立的结点将不会遍历。
package graphDFS;
import java.util.ArrayList;
public class GraphDFS {
// 创建一个数组,
private ArrayList<Integer> res = new ArrayList<>(); // 输出最后深度优先遍历的结果
private boolean[] visited;
private Graph graph;
public GraphDFS(Graph graph) {
this.graph = graph;
visited = new boolean[graph.V()]; // 结点的数量
//dfs(0);
// 改进的地方:对每一个结点进行遍历
for (int v = 0; v < graph.V(); v++) {
if (!visited[v]) {
dfs(v);
}
}
}
private void dfs(int v) {
visited[v] = true;
res.add(v);
for (int w: graph.adj(v)) { // 遍历该节点的相邻结点
if (! visited[w])
dfs(w);
}
}
public Iterable<Integer> res(){
return res;
}
public static void main(String[] args) {
Graph graph = new Graph("g2.txt");
GraphDFS graphDFS = new GraphDFS(graph);
System.out.println(graphDFS.res());
// [0, 1, 3, 2, 6, 5, 4]
}
}
。。。。。。。。。。。。。end。。。。。。。。。。。。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。