【圖論】廣度優先搜索和深度優先搜索

【圖論】廣度優先搜索和深度優先搜索


寫在最前面的

兩種圖的遍歷算法在其他圖的算法當中都有應用,並且是基本的圖論算法。

 

廣度優先搜索

廣度優先搜索(BFS),可以被形象的描述爲“淺嘗輒止”,具體一點就是每個頂點只訪問它的鄰接節點(如果它的鄰接節點沒有被訪問)並且記錄這個鄰接節點,當訪問完它的鄰接節點之後就結束這個頂點的訪問。

廣度優先用到了“先進先出”隊列,通過這個隊列來存儲第一次發現的節點,以便下一次的處理;而對於再次發現的節點,我們不予理會——不放入隊列,因爲再次發現的節點:

  1. 無非是已經處理完的了;
  2. 或者是存儲在隊列中尚未處理的。

image

《算法導輪》對兩種搜索都採用了很聰明的做法,用白色WHITE來標誌未發現的節點,用灰色GRAY來標誌第一次被發現的節點,用黑色BLACK來標誌第二次被發現的節點。

於是有了:

導輪還在上面僞代碼的“其他”中加入了訪問長度和父節點的操作。此舉可以算出,從源點到其他頂點路徑的最少步數和它的具體路徑。

關於廣度優先搜索的一個簡單應用:

假如有問題,每個村莊之間都通過橋來聯通,先給出村莊的圖,問村莊A到村莊B最少要通過多少座橋?這個問題可以很容易的轉化爲上面的BFS問題。

深度優先搜索

深度優先搜索(DFS),可以被形象的描述爲“打破沙鍋問到底”,具體一點就是訪問一個頂點之後,我繼而訪問它的下一個鄰接的頂點,如此往復,直到當前頂點一被訪問或者它不存在鄰接的頂點。

同樣,算法導論採用了“聰明的做法”,用三種顏色來標記三種狀態。但這三種狀態不同於廣度優先搜索:

  1. WHITE 未訪問頂點
  2. GRAY 一條深度搜索路徑上的頂點,即被發現時
  3. BLACK 此頂點的鄰接頂點被全部訪問完之後——結束訪問次頂點

image

通過給DFS搜索過程中給每一個頂點加時間戳,就可以實現拓撲排序了。實現拓撲排序需要:

對於每一個頂點,都有兩個時間戳,分別這樣來定義:

  1. 在一頂點剛被發現的時候,標記此頂點的第一個時間戳;
  2. 在結束此頂點的訪問的時候,標記此頂點的第二個時間戳。時間戳可以用簡單的123456來標記,只要能區分大小就行。
因此,你會發現,越早發現的點,他的第一個時間戳會越小,但是他的第二個時間戳會越大。 

總結

兩個算法都是O(V+E),在用到的時候適當選取。在使用白灰黑標誌的時候,突然明白瞭如何用深度優先搜索來判斷有向圖中是否存在環。

深度優先和廣度優先各有各的優缺點:

 

  • 廣優的話,佔內存多,能找到最優解,必須遍歷所有分枝. 廣優的一個應用就是迪科斯徹單元最短路徑算法.
  • 深優的話,佔內存少,能找到最優解(一定條件下),但能很快找到接近解(優點),可能不必遍歷所有分枝(也就是速度快), 深優的一個應用就是連連看遊戲.

 

在更多的情況下,深優是比較好的方案。

 

本文完 2012-05-16

搗亂小子 http://www.daoluan.net

更多請訪問:http://daoluan.net
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章