深度優先搜索算法
- 深度優先遍歷,從初始訪問結點出發,初始訪問結點可能有多個鄰接結點,深度優先遍歷的策略就是首先訪問第一個鄰接結點,然后再以這個被訪問的鄰接結點作為初始結點,訪問它的第一個鄰接結點,可以這樣理解:每次都在訪問完當前結點后首先訪問當前結點的第一個鄰接結點。
- 我們可以看到,這樣的訪問策略是優先往縱向挖掘深入,而不是對一個結點的所有鄰接結點進行橫向訪問。
- 顯然,深度優先搜索是一個遞歸的過程。

算法分析:
- 假設起始節點為1;先搜索1節點的右側鄰接節點為2,此時將1節點置為已搜索狀態;判斷2節點是否為已搜索狀態,若未搜索,則將2節點置為已搜索狀態;每次都優先搜索判斷右側鄰接節點;
- 如圖所示,若此時已搜索至5節點,發現右側鄰接節點為2且已處於已搜索狀態;故遞歸至上一個節點8搜索左側鄰接節點處...層層遞歸判斷至1節點(在圖中沒有並表明遞歸路徑);
- 此時搜索判斷1節點的左側鄰接節點3不為已搜索狀態,故繼續進行先右側后左側鄰接節點搜索判斷操作;
- 直至最后一個節點6搜索判斷3節點為已搜索狀態,故遞歸至最初的1節點;判斷結束,搜索結束。
代碼實現:
// 對dfs進行一個重載,遍歷我們所有的結點,並進行dfs
public List<Integer> DFS() {
isSreachs = new boolean[vertexList.size()];
dfsArrays = new ArrayList<>();
for (int i = 0; i < vertexList.size(); i++) {
// 遍歷所有的結點,進行dfs[回溯]
if (!isSreachs[i]) {
dfsArrays = DFS(isSreachs[i], i);
}
}
return dfsArrays;
}
public List<Integer> DFS(boolean isSreach, int i) {
// 首先我們將該節點添加進數組
dfsArrays.add(showVertexList(i));
// 將節點設置為已經訪問
isSreachs[i] = true;
// 查找節點i的第一個鄰接節點w
int w = getFirstNeighbor(i);
while (w != -1) { // 說明存在w
if (!isSreachs[w]) {
DFS(isSreachs[w],w);
}
// w節點已經被訪問過
w = getNextNeightbor(i,w);
}
return dfsArrays;
}
// 得到第一個鄰接結點的下標
public int getFirstNeighbor(int index) {
for (int j = 0; j < vertexList.size(); j++) {
if (edges[index][j] == 1) {
return j;
}
}
return -1;
}
// 根據前一個鄰接結點的下標來獲取下一個鄰接結點
public int getNextNeightbor(int v1, int v2) {
for (int i = v2+1; i < vertexList.size(); i++) {
if (edges[v1][i] == 1) {
return i;
}
}
return -1;
}
實現結果:

這里的結果與分析的結果有所出入,這是因為分析中借用了樹的概念,在實現中需要左右子樹遞歸。而這里則運用了上一節圖中鄰接矩陣的概念,將邊用二維矩陣的形式表示出來,故搜索順序會有些出入。
但所用的思想是一致的:一條路走到黑,再回頭。
