C 演算法之深度優先搜尋演算法詳解

2021-08-28 11:46:44 字數 3881 閱讀 2953

1.深度優先搜尋演算法

2.實現原理

深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs即depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次.

舉例說明之:下圖是乙個無向圖,如果我們從a點發起深度優先搜尋(以下的訪問次序並不是唯一的,第二個點既可以是b也可以是c,d),則我們可能得到如下的乙個訪問過程:a->b->e(沒有路了!回溯到a)->c->f->h->g->d(沒有路,最終回溯到a,a也沒有未訪問的相鄰節點,本次搜尋結束).簡要說明深度優先搜尋的特點:每次深度優先搜尋的結果必然是圖的乙個連通分量.深度優先搜尋可以從多點發起.如果將每個節點在深度優先搜尋過程中的"結束時間"排序(具體做法是建立乙個list,然後在每個節點的相鄰節點都已被訪問的情況下,將該節點加入list結尾,然後逆轉整個鍊錶),則我們可以得到所謂的"拓撲排序",即topological sort. 

深度優先遍歷圖的方法是,從圖中某頂點v出發:

(1)訪問頂點v;

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

(3)若此時圖中尚有頂點未被訪問,則從乙個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過為止。當然,當人們剛剛掌握深度優先搜尋的時候常常用它來走迷宮.事實上我們還有別的方法,那就是廣度優先搜尋(bfs).

3.演算法框架及說明

所有的搜尋演算法從其最終的演算法實現上來看,都可以劃分成兩個部分──控制結構和產生系統。正如前面所說的,搜尋演算法簡而言之就是窮舉所有可能情況並找到合適的答案,所以最基本的問題就是羅列出所有可能的情況,這其實就是一種產生式系統。我們將所要解答的問題劃分成若干個階段或者步驟,當乙個階段計算完畢,下面往往有多種可選選擇,所有的選擇共同組成了問題的解空間,對搜尋演算法而言,將所有的階段或步驟畫出來就類似是樹的結構(如圖)。從根開始計算,到找到位於某個節點的解,回溯法(深度優先搜尋)作為最基本的搜尋演算法,其採用了一種「乙隻向下走,走不通就掉頭」的思想(體會「回溯」二字),相當於採用了先根遍歷的方法來構造搜尋樹。

4.深度優先演算法**實現

bool visited[maxvnum];

void dfs(graph g,int v)

arcnode; //邊節點的型別

typedef struct vnode

vnode; //鄰接表頭節點型別

typedef vnode adjlist[maxv];

typedef struct

algraph; //完整的圖鄰接表型別

void arraytolist(int *arr, int n, algraph *&g) //用普通陣列構造圖的鄰接表

g->e=count;}

void dispadj(algraph *g) //輸出鄰接表g

printf("\n");

}} /*判斷圖g中從頂點u到v是否存在簡單路徑:

在深度優先遍歷的基礎上增加has和v兩個形參,其中has表示頂點u到v是否有路徑,其初值為false,

當頂點u遍歷到頂點v後,置has為true並返回。

*/void existpath(algraph *g,int u,int v,bool &has)

p=g->adjlist[u].firstarc; //p指向頂點u的第乙個鄰接點

while(p!=null)

} /*輸出圖g中從頂點u到v的一條簡單路徑:

在深度優先遍歷的基礎上增加v、path和d三個形參,其中path存放頂點u到v的路徑,d表示path中的路徑長度,初值為-1

當頂點u遍歷到頂點v後,輸出path並返回。

*/void findapath(algraph *g,int u,int v,int path,int d)}

/*輸出從圖g中從頂點u到v的所有簡單路徑:

在深度優先遍歷的基礎上增加v、path和d三個形參,其中path存放頂點u到v的路徑,d表示path中的路徑長度,初值為-1

當從頂點u出發遍歷時,先將visited[u]置為1,並將u加入到路徑path中,若滿足頂點u就是終點的v的條件時,

則找到了乙個從頂點u到v的一條路徑,則輸出path並繼續;再從頂點u找乙個未訪問過的相鄰頂點w,若存在這樣的頂點w,

則從w出發繼續進行,若不存在這樣的頂點w,則說明從頂點u再往下找找不到路徑,所以置visited[u]為0,以便頂點u作為

其他路徑上的頂點。

*/void findpath(algraph *g,int u,int v,int path,int d)

visited[u]=0; //恢復環境,使該頂點可重新使用}

/*輸出從圖g中從頂點u到v的長度為s的所有簡單路徑;

只需將路徑輸出條件改為u==v且d==s。

*/void pathall(algraph *g,int u,int v,int s,int path,int d)

visited[u]=0; //恢復環境,使該頂點可重新使用}

/*求圖中通過某頂點k的所有簡單迴路(若存在):

利用深度優先搜尋方法,從頂點u開始搜尋與之相鄰的頂點w,若w等於頂點v(其初值為u),且路徑長度大於0,表示找到了一條迴路,

*/void dfspath(algraph *g,int u,int v,int path,int d)

visited[u]=0; //恢復環境,使該頂點可重新使用}

int main()

, ,,,

};int b[5][5]=,,

,,};int c[5][5]=,,

,,};arraytolist(a[0], 5, g);

arraytolist(b[0], 5, g1);

arraytolist(c[0], 5, g2);

for (i=0; in; i++)

visited[i]=0; //訪問標誌陣列初始化

printf("有向圖g的鄰接表:\n");

dispadj(g);

cout

visited[i]=0; //訪問標誌陣列初始化

existpath(g,1,4,f);

cout<

if(f)

cout<

visited[i]=0; //訪問標誌陣列初始化

cout

visited[i]=0; //訪問標誌陣列初始化

printf("無向圖g1的鄰接表:\n");

dispadj(g1);

cout

visited[i]=0; //訪問標誌陣列初始化

printf("輸出g1從1到4的所有簡單路徑:\n");

findpath(g1,1,4,path,-1);

cout

visited[i]=0; //訪問標誌陣列初始化

cout<

pathall(g1,1,4,3,path,-1);

cout

visited[i]=0; //訪問標誌陣列初始化

printf("有向圖g2的鄰接表:\n");

dispadj(g2);

cout

visited[i]=0; //訪問標誌陣列初始化

cout<

dfspath(g2,0,0,path,-1);

cout程式執行輸出:

深度優先搜尋演算法

include include define vertexnum 9 struct node typedef struct node graph struct node head vertexnum 定義圖形結構 int visited vertexnum 頂點陣列 深度優先搜尋 void dfs ...

深度優先搜尋演算法

今天我們來複習一下萬能的搜尋演算法之深度優先搜尋演算法。深度優先搜尋演算法顧名思義就是按照樹的延伸不停的往下搜尋,直到樹的盡頭之後再一步一步的回溯回來。好吧,我們直接問你乙個問題,給你乙個數n,讓你輸出從1到這個樹的全排列,你會怎麼寫,會不會想到去用若干個for迴圈?好吧,你肯定錯了,其實他考的就是...

深度優先搜尋演算法

1.深度優先搜尋演算法的概念 深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個 節點只能訪問一次。如下例 該圖為乙個無向圖,假設我們從a開始進行深度優先搜尋,第二點可以是b c d中任意乙個,...