十 深度優先搜尋(DFS)

2021-07-11 06:51:19 字數 1600 閱讀 2889

深度優先搜尋演算法(depth-first-search),是搜尋演算法的一種。它沿著樹的深度遍歷樹的節點,盡可能深的搜尋樹的分 支。當節點v 的所有邊都己被探尋過,搜尋將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點為止。如果還存在未被發 現的節點, 則選擇其中乙個作為源節點並重複以上過程,整個程序反覆進行直到所有節點都被訪問為止。dfs屬於盲目搜尋。

深度優先搜尋是圖論中的經典演算法,利用深度優先搜尋演算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。一般用堆資料結構來輔助實現dfs演算法。

1. 訪問頂點v;

2. 依次從v的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和v有路徑相通的頂點都被訪問;

3. 若此時圖中尚有頂點未被訪問,則從乙個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過為止。

下圖是乙個

無向圖,如果我們從a點發起深度優先搜尋(以下的訪問次序並不是唯一的,第二個點既可以是b也可以是c,d),則我們可能得到如下的乙個訪問過程:a->b->e(沒有路了!

回溯到a)->c->f->h->g->d(沒有路,最終

回溯到a,a也沒有未訪問的相鄰

節點,本次搜尋結束).

簡要說明深度優先搜尋的特點:每次深度優先搜尋的結果必然是圖的乙個連通分量.深度優先搜尋可以從多點發起.如果將每個節點在深度優先搜尋過程中的"結束時間"排序(具體做法是建立乙個list,然後在每個節點的相鄰節點都已被訪問的情況下,將該節點加入list結尾,然後逆轉整個鍊錶),則我們可以得到所謂的"

拓撲排序

",即topological sort。

定義乙個結構體來表達乙個node的結構:

struct node  ;
那麼我們在搜尋乙個樹的時候,從乙個

節點開始,能首先獲取的是它的兩個子節點。

a           b           c      d   e          f   g

a是第乙個訪問的,然後順序是b和d、然後是e。然後再是c、f、g。那麼我們怎麼來保證這個順序呢?

這裡就應該用

堆疊的結構,因為堆疊是乙個先進後出的順序。通過使用

c++的

stl,下面的程式能幫助理解:

const int tree_size = 9; 

std::stackvisited, unvisited;

node nodes[tree_size];

node* current;

for( int i=0; iright!=null)

unvisited.push(current->right); // 把右邊壓入 因為右邊的訪問次序是在左邊之後

if(current->left!=null)

unvisited.push(current->left);

visited.push(current);

cout

深度優先搜尋DFS

作為搜尋演算法的一種,dfs對於尋找乙個解的 np 包括npc 問題作用很大。但是,搜尋演算法畢竟是 時間複雜度是o n 的階乘級演算法,它的效率比較低,在資料規模變大時,這種演算法就顯得力不從心了。關於深度優先搜尋的效率問題,有多種解決方法。最具有通用性的是剪枝 prunning 也就是去除沒有用...

深度優先搜尋 DFS

深度優先搜尋 縮寫dfs 有點類似廣度優先搜尋,也是對乙個連通圖進行遍歷的演算法。它的思想是從乙個頂點v 0開始,沿著一條路一直走到底,如果發現不能到達目標解,那就返回到上乙個節點,然後從另一條路開始走到底,這種盡量往深處走的概念即是深度優先的概念。你可以跳過第二節先看第三節,還是引用上篇文章的樣例...

深度優先搜尋(dfs)

深度優先搜尋的一般步驟 1 從頂點v出發,訪問v。2 找出剛才訪問過的頂點的第乙個未被訪問的鄰接點,訪問該頂點。以該頂點為新頂點,重複此步驟,直到剛訪問的頂點沒有沒有未被訪問過的鄰接點為止。3 返回前乙個訪問過的仍有未被訪問過的鄰接點的頂點,找出該頂點的下乙個未被訪問過的鄰接點,訪問該頂點。4 重複...