学习图的遍历之前得知道图的表示方法
可以参考
图的表示方法
进入正题
什么是图的深度遍历算法
所谓深度遍历 就是一口气一条路走到底,再回溯重复便可达到遍历效果
一组图片来说明这个问题
深度遍历这个图
第一步
第二步
依次遍历直到到最底部
到达底部后 回溯重复 也就是回溯到C
然后,C开始访问未访问的边,也是访问到底部
F回溯到E E开始访问未访问的边
D回溯 到 E E开始访问未访问的边
到此所有的节点已经访问完成 但是程序并未停止直到回溯至A点(递归的特性)
上面的图片非常清楚的描述了深度遍历的过程
接下来我将用Java实现这个算法
水平有限 若有错误 欢迎指正
//这里使用的是邻接矩阵方法
public class DFS {
GraphByMatrix graphByMatrix = new GraphByMatrix(10);
Stack<Node> stack;
List<Node> list;
class Node {
// 节点数据
String str;
boolean visited;
// 该节点对应在关系矩阵中的编号
int numner;
public Node(String str, int num) {
this.str = str;
this.numner = num;
}
}
public DFS() {
stack = new Stack<>();
list = new ArrayList<Node>();
for (int i = 0; i < 8; i++) {
// 节点内容分别为A-H 对应编号0-7
list.add(new Node(new String(Character.toChars('A' + i)), i));
}
}
public void Dfs() {
// 被访问过
list.get(7).visited = true;
System.out.print(list.get(7).str + " ");
// 被访问过后压入栈
stack.push(list.get(7));
// 栈不为空则没有遍历完全
while (!stack.isEmpty()) {
// 返回栈顶元素
Node peek = stack.peek();
int nextVertex = getNextVertex(peek);
// 没找到 证明所有边都已经遍历
if (nextVertex == -1) {
// 删除这个顶点
stack.pop();
// 找到了 将这个点作为下一次的顶点
} else {
list.get(nextVertex).visited = true;
System.out.print(list.get(nextVertex).str + " ");
stack.push(list.get(nextVertex));
}
}
}
// 递归
public void DFs(int index, List<Node> list) {
//访问到底部或者该节点没有未访问的边
if (index == -1)
return;
Node node = list.get(index);
node.visited = true;
System.out.print(node.str + " ");
while (getNextVertex(node) != -1)
DFs(getNextVertex(node), list);
}
//获取与Node 相连的未访问的边
public int getNextVertex(Node peek) {
boolean[][] matrix = graphByMatrix.matrix;
for (int i = 0; i < matrix.length; i++) {
// 查找顶点没有访问过的节点
if (matrix[peek.numner][i] == true && list.get(i).visited == false) {
return i;
}
}
return -1;
}
//建立图 用来测试的
public void bulid() {
//描述关系 这里是双向边 所以 A B 相连后不需要 B A相连会自动连上
//A B 相连
graphByMatrix.addEdge(0, 1);
//B C 相连
graphByMatrix.addEdge(1, 2);
//B D 相连
graphByMatrix.addEdge(1, 3);
//C G 相连
graphByMatrix.addEdge(2, 6);
// C E 相连
graphByMatrix.addEdge(2, 4);
// D E 相连
graphByMatrix.addEdge(3, 4);
// E F 相连
graphByMatrix.addEdge(4, 5);
// E H 相连
graphByMatrix.addEdge(4, 7);
}
}
测试代码
public static void main(String[] args) {
DFS dfs = new DFS();
dfs.bulid();
dfs.Dfs(0);
}
结果
A E C B D G F H
发现和上面推理的顺序不一样原因在于矩阵法的构建
节点会找矩阵中离他近的边
图片只是描述深度遍历的过程,当一个节点有多条未访问的边,选择的不同,会导致结果的不一样。
到此深度遍历差不多结束了。