1. 程式人生 > >18.深度優先搜尋(DFS)

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 π   //返回變灰色點,變黑色點時間以及父節點

如下圖所示: