思想:對於最新發現的頂點v,若是它還有以此爲起點而還未探索的邊,沿此邊探索。若是v的全部邊已經探索完了,再回溯到發現v有起始點的那些邊。一直到已經探索了從源起點可到的全部頂點爲止。若是還有沒探索的頂點,將它定義爲一個新的源頂點,繼續上述過程。算法
像走迷宮同樣,嘗試每種可能的結果,沒走通,就回溯到當初分叉的路口,繼續探索bash
DFS(V,Adj):
parent={}
for s in V: //遍歷圖中全部的點
if s not in parent: //點沒有遍歷過就繼續探索
parent[s]=None //源點不設置父節點
DFS-Visit(Adj,s) //探索當前源頂點可以到達的全部的點
複製代碼
DFS-Visit(Adj,s):
for v in Adj[s]: //遍歷全部的邊
if v not in parent: //當前邊沒有遍歷過
parent[v]=s //記錄已經遍歷
DFS-Visit(adj,v) //優先探索當前節點的邊,完成以後,再執行回溯(經過循環實現)
複製代碼
以有向圖爲例
假設按照字母的順序來遍歷全部的頂點,即V=[a,b,c,d,e,f],原始的圖爲spa
深度優先樹指的是通過DFS生成的樹,結果爲3中的橙色箭頭所指的兩個部分.net
O(V+E);它的遍歷規則仍然須要遍歷全部的節點一遍,對於每條變來說,只有沒有遍歷過的才作一次遍歷3d
在算法中,樹邊判斷經過parent就能夠看出,parent的逆向就是樹邊,得以標識;code
反邊判斷,能夠在源點開始作一個標記,把全部的通過的節點都放入棧中,若是下次獲得的頂點在棧中,那麼這條邊就是反邊;cdn
圖G存在環,當且僅當圖中存在一條反邊。證實以下:blog
Job自己是個無環的有向圖,各個頂點之間一定存在着必定的順序,執行的時候等前面的執行完才能再執行排在後面的排序
它使用的算法稱做拓撲排序,拓撲排序內部使用的就是DFS,輸出爲完成時的頂點的逆序,就排序好了(以前記錄的是parent的指向,真正的執行是先parent)it
這種排序產生的結果是,假設圖中全部的頂點放在同一個水平線上,那麼全部的方向均是從左到右
證實
只須要證實,對於任何一個邊e=(u,v),在v執行完以後,u才執行完
算法導論(MIT 6.006 第14講)