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中任意乙個,...