2-1 图的两种形式遍历


所谓图的 遍历graph traversal ),也称为 搜索search ),就是从图中某个顶点出发,沿着一 些边访遍图中所有的顶点,且使


 


每个顶点仅被访问一次。遍历可以采取两种方法进行:深度优先搜索(DFS,depth first search


 


和广度优先搜索( BFS , breadth first search )。


 

2-2 图的深度优先遍历伪代码


深度优先搜索 是一个递归过程,有回退过程。 DFS 算法的思想是:对一个无向连通图,在访问图中某一起始顶点 v 后,由 v 出、


 


发,访问它的某一邻接顶点 w 1 ;再从 w 1 出发,访问与 w 1 邻接但还没有访问过的顶点 w2;然后再从 w 2 出发,进行类似的访


 


问;…;如此进行下去,直至到达所有邻接顶点都被访问过的顶点 u 为止;接着,回退一步,回退到前一次刚访问过的顶点,看


 


是否还有其它没有被访问过的邻接顶点,如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就


 


再回退一步进行类似的访问。重复上述过程,直到该连通图中所有顶点都被访问过为止。


 


java 遍历代码画流程图 java实现图的遍历_图论

 


树的前序遍历,与图的深度优先遍历的比较:

java 遍历代码画流程图 java实现图的遍历_图论_02


2-3 DFS逻辑的微观解读,深度优先遍历顺序

深度优先遍历的递归的遍历形式:

java 遍历代码画流程图 java实现图的遍历_java 遍历代码画流程图_03

java 遍历代码画流程图 java实现图的遍历_图论_04

java 遍历代码画流程图 java实现图的遍历_算法_05

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 图的深度优先遍历的改进

如果不是联通图的话,孤立的结点将不会遍历。

java 遍历代码画流程图 java实现图的遍历_dfs_06

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]
	}

}