参考:http://www.cnblogs.com/skywang12345/p/3711483.html
一、深度优先搜索
图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。
它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
显然,深度优先搜索是一个递归的过程。
二、广度优先搜索
广度优先搜索算法(Breadth First Search),又称为”宽度优先搜索”或”横向优先搜索”,简称BFS。
它的思想是:从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2…的顶点。
三、Java代码实现
/*
* @date:2016-10-13
* @autor:crystal
* @description: DFS & BFS
*/
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class DepthFirstSearch {
private char[] vertexs;//顶点的字符集合
private boolean[][] edges; //存储边关系的布尔矩阵
public static void main(String[] args){
char[] vertexs = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char[][] edges = new char[][]{
{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'F', 'G'}};
DepthFirstSearch dfs = new DepthFirstSearch(vertexs, edges);
dfs.DFS();
System.out.println();
dfs.BFS();
}
//初始化操作,根据输入的顶点集合和边的关系,根据字符对数组初始化布尔矩阵
private void initial(char[] vertexs, char[][] edges){
int len = vertexs.length;
boolean[][] newEdges = new boolean[len][len];
ArrayList<Character> al = new ArrayList<Character>(len);
for(int i = 0; i < len; i++){
al.add(vertexs[i]);
}
for(int i = 0; i < edges.length; i++){
int index1 = al.indexOf(edges[i][0]);
int index2 = al.indexOf(edges[i][1]);
newEdges[index1][index2] = true;
newEdges[index2][index1] = true; //如果是有向图删除这一行
}
this.edges = newEdges;
this.vertexs = vertexs;
}
DepthFirstSearch(char[] vertexs, char[][] edgs){
initial(vertexs, edgs);
}
//根据节点v找到相邻的第一个节点
private int firstIndex(int v){
if(v < 0 || v > (vertexs.length -1))
return -1;
for(int i = 0; i < vertexs.length; i++)
if(edges[v][i])
return i;
return -1;
}
//由节点v找到相邻节点w的下一个相邻节点
private int nextIndex(int v, int w){
if(v < 0 || v > (vertexs.length -1) || w < 0 || w > (vertexs.length -1))
return -1;
for(int i = w+1; i < vertexs.length; i++)
if(edges[v][i])
return i;
return -1;
}
//递归实现深度优先搜索,私有实现
private void DFS(int i, boolean[] visited){
visited[i] = true;
System.out.print(vertexs[i]);
for(int j = firstIndex(i); j >= 0; j = nextIndex(i,j)){
if(!visited[j])
DFS(j, visited);
}
}
//公有实现,对外提供接口
public void DFS(){
int len = vertexs.length;
boolean[] visited = new boolean[len];
for(int i = 0 ; i < len; i++)
visited[i] = false;
for(int i = 0; i < len; i++){
if(!visited[i]){
DFS(i,visited);
}
}
}
//广度优先搜索
public void BFS()
{
int len = vertexs.length;
boolean[] visited = new boolean[len];
Queue<Integer> q = new LinkedList<Integer>(); //类似层次遍历,用队列来实现
for(int i = 0; i < len; i++)
visited[i] = false;
for(int i = 0; i < len; i++){
if(!visited[i]){
visited[i] = true;
System.out.print(vertexs[i]);
q.add(i);
}
while(!q.isEmpty()){
int v = q.poll();
for(int w = firstIndex(v); w >=0; w=nextIndex(v,w)){
if(!visited[w]){
visited[w] = true;
System.out.print(vertexs[w]);
q.add(w);
}
}
}
}
}
}