图的存储方式有两种:邻接矩阵和邻接表,这两种方式都可以用深度优先和广度优先的方式进行遍历。以下面的图为例说明遍历,其临街矩阵如作图所示。注意后面的代码中,顶点从0开始。
1. 深度优先
深度优先基于递归的思想,假设开始从顶点1开始遍历,找到其第一个相邻的顶点2,一直往“深”处遍历,找顶点2的相邻顶点4,再找顶点4的相邻点,直到没有相邻点或者相邻点都被访问过进行回溯,同理对其他顶点进行遍历,直到所有顶点都遍历完成。
关键点:
1. 对已访问过的点标记,使用book[][]数组
2. 结束条件,所有顶点都访问完。
3. 图 矩阵的初始化
java实现如下:
package aha_algorithm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Scanner;
public class Graph {
static int traversedNum;
static int totalVertex=5;
static int[][] graph= new int[5][5];
static int book[] = new int[5];
/** * @param args */
public static void main(String[] args) {
initGraph();
book[0]=1;
DFS(0);
}
public static void DFS(int curVertex){
System.out.println(curVertex);
traversedNum++;
//结束条件
if(traversedNum==totalVertex)
return;
for (int i = 0; i <graph[curVertex].length ; i++) {
if(graph[curVertex][i]==1 && book[i]!=1){
book[i]=1;
DFS(i);
//不需要清除标记
}
}
}
//输入图的边,初始化矩阵
static void initGraph(){
for (int i = 0; i <5; i++) {
for (int j = 0; j < 5; j++) {
graph[i][j]=Integer.MAX_VALUE;
}
}
BufferedReader input =new BufferedReader(new InputStreamReader(System.in));
for (int i = 0; i < 5; i++) {
try {
String[] inLine=input.readLine().split(" ");
//双向图
graph[Integer.valueOf(inLine[0])][Integer.valueOf(inLine[1])]=1;
graph[Integer.valueOf(inLine[1])][Integer.valueOf(inLine[0])]=1;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2. 广度优先
广度优先基于队列实现,遍历顺序是:遍历顶点1,将顶点1的所有邻接点加入对列,直到顶点1的相邻点都在队列了将顶点1出队同时访问顶点1,从顶点1的第一个邻接点2开始,将顶点2的所有相邻顶点放入队列,依次类推。结束条件是队列为空。
关键点:
1. 初始化矩阵
2. 创建队列
3. 遍历顶点的相邻点入队
4. 标记顶点已经被访问
5. 判断是否存在通路
java实现如下:
package aha_algorithm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;
public class Graph {
static int traversedNum;
static int totalVertex=5;
static int[][] graph= new int[5][5];
static int book[] = new int[5];
static Queue<Integer> bfsQueue = new ArrayDeque<Integer>();
/** * @param args */
public static void main(String[] args) {
initGraph();
bfsQueue.offer(0);
book[0]=1;//注意标记初始点
BFS();
}
public static void BFS( ){
while(!bfsQueue.isEmpty()){
int curVer =bfsQueue.peek();
for (int i = 0; i < 5; i++) {
if(graph[curVer][i]==1 && book[i]==0){
bfsQueue.offer(i);//将邻接顶点入队
book[i]=1;
}
}
System.out.println(curVer);
bfsQueue.poll();//将已经访问过的顶点出队
}
}
//输入图的边,初始化矩阵
static void initGraph(){
for (int i = 0; i <5; i++) {
for (int j = 0; j < 5; j++) {
graph[i][j]=Integer.MAX_VALUE;
}
}
BufferedReader input =new BufferedReader(new InputStreamReader(System.in));
for (int i = 0; i < 5; i++) {
try {
String[] inLine=input.readLine().split(" ");
//双向图
graph[Integer.valueOf(inLine[0])][Integer.valueOf(inLine[1])]=1;
graph[Integer.valueOf(inLine[1])][Integer.valueOf(inLine[0])]=1;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
深度优先遍历可以查看另一片文章,DFS走迷宫