/**
* 图的遍历方式:深度优先遍历和广度优先遍历-》先创建图的邻接矩阵,求出某个顶点的第一个链接顶点-》如果某个顶点有好多个连通的顶点,求与之连通的第2个顶点的下一个顶点的位置
* -》深度优先遍历:先遍历某个顶点的第一个连通的顶点-》迭代的方式找到改顶点的下个第一个顶点
*
* @author timmy1
*
*/
public class GraphTraverse {
int[][] matrix;// 矩阵
int MAX_WEIGHT = Integer.MAX_VALUE;
int size;// 顶点个数
boolean[] isVisted;// 标示顶点是否被访问过
private void createGraph(int index) {
size = index;
matrix = new int[index][index];
int[] a0 = { 0, 10, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT };
int[] a1 = { 10, 0, 18, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, MAX_WEIGHT, 12 };
int[] a2 = { MAX_WEIGHT, MAX_WEIGHT, 0, 22, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 8 };
int[] a3 = { MAX_WEIGHT, MAX_WEIGHT, 22, 0, 20, MAX_WEIGHT, 24, 16, 21 };
int[] a4 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 20, 0, 26, MAX_WEIGHT, 7, MAX_WEIGHT };
int[] a5 = { 11, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 26, 0, 17, MAX_WEIGHT, MAX_WEIGHT };
int[] a6 = { MAX_WEIGHT, 16, MAX_WEIGHT, 24, MAX_WEIGHT, 17, 0, 19, MAX_WEIGHT };
int[] a7 = { MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 16, 7, MAX_WEIGHT, 19, 0, MAX_WEIGHT };
int[] a8 = { MAX_WEIGHT, 12, 8, 21, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 0 };
matrix[0] = a0;
matrix[1] = a1;
matrix[2] = a2;
matrix[3] = a3;
matrix[4] = a4;
matrix[5] = a5;
matrix[6] = a6;
matrix[7] = a7;
matrix[8] = a8;
}
// 深度优先遍历
public void DFS() {
isVisted = new boolean[size];
for (int j = 0; j < size; j++) {
if (!isVisted[j]) {
PrintUtil.print("访问到第:" + j + "顶点");
depthFirstSearch(j);
}
}
}
/**
* 图的深度优先算法实现
*
* @param i
* 标示第几个顶点
*/
private void depthFirstSearch(int i) {
isVisted[i] = true;
// 先找到改顶点的第一个连通顶点下标
int vertex = getFirstVertex(i);
while (vertex != -1) {// 存在第一个连通的顶点-》是否已经访问过->没有访问过-》访问-》再以该新顶点深度遍历
if (!isVisted[vertex]) {
isVisted[vertex] = true;
PrintUtil.print("访问到第:" + vertex + "顶点");
depthFirstSearch(vertex);
}
vertex = getNextVertex(i, vertex);
}
}
//广度优先遍历
private void BFS() {
isVisted = new boolean[size];
for (int j = 0; j < size; j++) {
if (!isVisted[j]) {
PrintUtil.print("访问到第:" + j + "顶点");
broadFirstSearch(j);
}
}
}
/**
* 图的广度优先遍历实现:采用队列进行辅助,使用队列的增加和删除元素的方法-》实现思路为:先获取到某个顶点,-》该顶点第一个顶点-》第一个顶点后的顶点
* @param j
*/
private void broadFirstSearch(int j) {
int firstVertex;
LinkedList<Integer> list = new LinkedList<Integer>();
isVisted[j] = true;
list.add(j);
while(!list.isEmpty()){
int vertex = list.removeFirst();//前面保存的顶点
firstVertex = getFirstVertex(vertex);//第一个顶点
while(firstVertex != -1){
if(!isVisted[firstVertex]){
isVisted[firstVertex] = true;
PrintUtil.print("访问到第:" + firstVertex+ "顶点");
list.add(firstVertex);
}
//拿到下一个顶点->赋值
firstVertex = getNextVertex(vertex, firstVertex);
}
}
}
/**
* 找到顶点i的第一个连通的顶点
*
* @param i
* @return 顶点下标,-1表示该顶点没有与之连通的顶点
*/
private int getFirstVertex(int i) {
for (int j = 0; j < size; j++) {
if (matrix[i][j] > 0 && matrix[i][j] < MAX_WEIGHT) {
return j;
}
}
return -1;
}
/**
* 求顶点base,第index顶点后的下一个顶点
*
* @param base
* @param index
* @return
*/
private int getNextVertex(int base, int index) {
for (int j = index + 1; j < size; j++) {
if (matrix[base][j] > 0 && matrix[base][j] < MAX_WEIGHT) {
return j;
}
}
return -1;
}
public static void main(String[] args) {
GraphTraverse graph = new GraphTraverse();
graph.createGraph(9);
// graph.DFS();
graph.BFS();
}
}