學習圖的遍歷之前得知道圖的表示方法
可以參考
圖的表示方法
進入正題
什麼是圖的深度遍歷算法
所謂深度遍歷 就是一口氣一條路走到底,再回溯重複便可達到遍歷效果
一組圖片來說明這個問題
深度遍歷這個圖
第一步
第二步
依次遍歷直到到最底部
到達底部後 回溯重複 也就是回溯到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
發現和上面推理的順序不一樣原因在於矩陣法的構建
節點會找矩陣中離他近的邊
圖片只是描述深度遍歷的過程,當一個節點有多條未訪問的邊,選擇的不同,會導致結果的不一樣。
到此深度遍歷差不多結束了。