18.深度優先搜尋(DFS)
深度優先搜尋是以源頂點作為根來建立深度優先樹,不過不同於廣度優先樹的建立,深度優先搜尋建立的乃是樹林(包含一棵或是說多棵)。
廣度優先表示的是從源頂點出發,每次都摸索周圍最近的鄰近點,鄰近點再想外摸索鄰近點,直至全部點探索完畢
深度優先表示的是從源頂點出發,一條路走到黑,其中要是發現走不通的,就開始返回,返回的途中要是發現有新的交叉路口,就往新的路探索一番,然後在回來。這條路走完回來後再從另一個源頂點出發,繼續一條路走下去直至所有的路都被走過。
輸入:圖G=<V,E>
輸出:圖中各頂點在搜尋過程中的發現時間和完成時間
接下來要分析一波虛擬碼,由於上述已經說過,深度優先搜尋是一條路走到黑然後再返程回來,所以這裡的S表示的是一個棧,能保證輸入頂點先進後出,然後還設定了一個time作為時間的全域性變數(其實也就是記錄該頂點變灰色與變黑色的次序),要求其中經過一次的頂點會變灰色,經過兩次的會變黑色,一個頂點有且必須進過兩次。
演算法虛擬碼:
DFS(G)
1. for each vertex u∈V[G] //遍歷每個頂點
2. do color[u]<-WHITE //將每個頂點初始化為白色
3. π[u]<-NIL //π陣列用來存放該過程的父節點
4. time<-0
5. S<-∅ //存放灰色點
6. for each vertex s∈V[G] //開始用源頂點走起
7. do if color[s]=WHITE
8. then color[s]<-GRAY
9. d[s]<-time<-time+1 //記錄該點開始時間
10. PUSH(S,s) //將該點放置於存放灰色點陣列中
11. while S≠∅
12. do u<-TOP(S) //表示該陣列的最上面的點
13. if 存在一個v屬於Adj[u] and color[v]=WHITE //存在一個點是u的附近點(Adj)且該點還沒有經過
14. then color[v]<-GRAY
15. π[v]<-u
16. d[v]<-time<-time+1
17. PUSH(S,v)
18. else color[u]<-BLACK //如果已經沒有附近點了,就變黑返回上級點
19. f[u]<-time<-time+1 //記錄變黑點
20. POP(S) //將上一級的點變成棧首
21. return d,f,and π //返回變灰色點,變黑色點時間以及父節點
如下圖所示: