深度和廣度優先搜尋演算法

2021-09-24 07:53:55 字數 2597 閱讀 7258

在社交網路中,有乙個六度分割理論,具體是說,世界上任何互不相識的兩人,平均只需要六步就能夠建立起聯絡。乙個使用者的一度連線使用者就是他的好友,二度連線使用者就是他好友的好友,三度連線使用者就是他好友好友的好友。

給定乙個使用者,如何找出這個使用者的所有三度(包括一度、二度和三度)好友關係呢?

我們知道,演算法都是作用於某種具體的資料結構上的,而深度優先搜尋演算法和廣度優先搜尋演算法就是作用於圖這種資料結構的。

圖上的搜尋演算法,就是從圖中的乙個頂點出發,到另乙個頂點的路徑。圖有兩種儲存方法,鄰接矩陣和鄰接表,在這裡我們用鄰接表來儲存圖,並以無向圖作為例子,但這兩種演算法也同樣都可以應用在有向圖中。

// 無向圖

class

graph

}// 無向圖中一條邊的兩個頂點都要儲存

void

addedge

(int s, int t)

void

bfs(int s, int t)

; void

print

(int prev, int s, int t)

; void

recursivedfs

(int prev, int visited, int cur, int t)

; void

dfs(int s, int t);};

複製**

廣度優先搜尋(breadth-first-search),一般簡稱為 bfs。直觀地講,它其實就是一種地毯式層層推進的搜尋策略,即先查詢離起始頂點最近的,然後是次近的,依次往外搜尋。

下面這段**的功能是搜尋一條從頂點 s 到頂點 t 的一條最短的路徑。

void graph::print(int prev, int s, int t)

cout

<< t << ' ';

}// 從 s 到 t 的廣度優先搜尋

void graph::bfs(int s, int t)

; int prev[v] = ;

queue

vertex;

visited[s] = 1;

vertex.push(s);

for (int i = 0; i < v; i++) prev[i] = -1;

while(!vertex.empty())

vertex.push(temp);

visited[temp] = 1;}}

}}複製**

其中,有三個非常重要的輔助變數需要特別注意。

下面我們來看一下廣度優先搜尋的時間複雜度和空間複雜度。

最壞情況下,終止頂點 t 距離起始頂點 s 很遠,需要遍歷完整個圖才能找到。這時候,每個頂點都要進出一遍佇列,每條邊也都會被訪問一次。所以,廣度優先搜尋的時間複雜度為 o(v+e),v 為頂點個數,e 為邊的條數。針對乙個所有頂點都是聯通的圖,e 肯定要大於 v-1,所以時間複雜度可以簡寫為 o(v)。

空間複雜度主要是三個變數所占用的額外空間,和頂點個數成正相關,為 o(v)。

深度優先搜尋(depth-first-search),簡稱 dfs,最直觀的例子就是走迷宮。

假設你站在迷宮的某個分岔路口,你想找到出口。你隨意選擇乙個岔路口來走,走著走著發現走不通的時候就原路返回到上乙個分岔路口,再選擇另一條路繼續走,直到找到出口,這種走法就是深度優先搜尋的策略。

上圖中,我們希望找到一條從 s 到 t 的路徑,其中實線表示向前遍歷,虛線表示回退。可以看到,深度優先搜尋到的並不是從 s 到 t 的最短路徑。

void graph::recursivedfs(int prev, int visited, int cur, int t)

for (unsigned

int i = 0; i < adjacent_list[cur].size(); i++)

}return;

}// 從 s 到 t 的深度優先搜尋

void graph::dfs(int s, int t)

; int prev[v] = ;

visited[s] = 1;

for (int i = 0; i < v; i++) prev[i] = -1;

recursivedfs(prev, visited, s, t);

print(prev, s, t);

}複製**

在深度優先搜尋演算法中,每條邊最多會被訪問兩次,一次是遍歷,一次是回退。所以,深度優先搜尋的時間複雜度為 o(e)。

visited、prev 陣列的大小為頂點個數,而遞迴函式呼叫棧的最大深度不會超過頂點的個數,所以深度優先搜尋的空間複雜度為 o(v)。

測試**如下,對應圖為上面廣度優先搜尋演算法中的例圖。

int

main

()複製**

查詢使用者的三度好友,也就是距離使用者 3 條邊以內的使用者。也就是說,在廣度優先演算法中,我們只需要向外查詢 3 層即可,可以通過乙個陣列記錄當前頂點與起始頂點的距離來實現。在深度優先演算法中,我們只需要控制最多隻從起始頂點遞迴 3 次即可,可以通過乙個變數記錄遞迴深度來實現。

參考資料-極客時間專欄《資料結構與演算法之美》

深度優先與廣度優先搜尋演算法

1.深度優先搜尋演算法 depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次.深度優先遍歷圖的方法是,從圖中某頂點v出發 1 訪問頂點v 2 依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷 直至圖中和v有路徑相通的頂點都被訪...

搜尋演算法(深度優先和廣度優先)(待更新 )

深度優先搜尋 dfs 基本思路 從圖中某定點v出發 訪問定點u 依次從u的未被訪問的鄰接點出發,對圖進行深度優先遍歷,直至圖中和v有路徑相通的頂點都被訪問。若此時圖中尚有未被訪問的定點,則從該頂點出發,重新進行深度優先遍歷,直至所有頂點均被訪問過為止。dfs演算法的具體 實現 const int m...

七十九 深度和廣度優先搜尋演算法

author runsen 程式設計的本質 於演算法,而演算法的本質 於數學,程式設計只不過將數學題進行 化。runsen 深度優先搜尋和廣度優先搜尋作為應用廣泛的搜尋演算法,一般是必考演算法。深度優先演算法的本質是回溯演算法,多數是應用在樹上,乙個比較典型的應用就是二叉樹的中序遍歷。dfs的實現考...