日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

DFS应用——遍历有向图+判断有向图是否有圈

發(fā)布時(shí)間:2023/12/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DFS应用——遍历有向图+判断有向图是否有圈 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【0】README

0.1) 本文總結(jié)于 數(shù)據(jù)結(jié)構(gòu)與算法分析, 源代碼均為原創(chuàng), 旨在 理解 “DFS應(yīng)用——遍歷有向圖+判斷有向圖是否有圈” 的idea 并用源代碼加以實(shí)現(xiàn) ;
0.2) 判斷有向圖是否有圈的rule—— 一個(gè)有向圖是無(wú)圈圖當(dāng)且僅當(dāng)它沒(méi)有背向邊,背向邊定義,參見: http://blog.csdn.net/pacosonswjtu/article/details/49967255 
0.3) 代碼最后還添加了打印dfs遍歷路徑所產(chǎn)生的集合, 對(duì)的,dfs 就應(yīng)該這么玩,Bingo!


【1】有向圖相關(guān)

1.1)對(duì)有向圖進(jìn)行DFS的idea:利用與無(wú)向圖相同的思路, 也可以通過(guò)深度優(yōu)先搜索以線性時(shí)間遍歷有向圖。如果圖不是強(qiáng)連通的,那么從某個(gè)節(jié)點(diǎn)開始的DFS可能訪問(wèn)不了所有的節(jié)點(diǎn)。在這種情況下, 我們?cè)谀硞€(gè)未作標(biāo)記的節(jié)點(diǎn)處開始,反復(fù)執(zhí)行DFS, 直到所有節(jié)點(diǎn)都被訪問(wèn)到;
1.2)基于以上描述, 我們看個(gè)荔枝(這只是一種可能的case):

  • step1)從頂點(diǎn)B 任意開始深度優(yōu)先搜索, 訪問(wèn)頂點(diǎn)B, C, A, D, E;
  • step2)從頂點(diǎn) F 任意開始DFS, 訪問(wèn)頂點(diǎn) F;
  • step3)從頂點(diǎn) H 任意開始DFS, 訪問(wèn)頂點(diǎn) H, J, I;
  • step4)從頂點(diǎn) G 任意開始DFS, 訪問(wèn)頂點(diǎn) G;

1.3)對(duì)于以上的DFS過(guò)程, 對(duì)應(yīng)的搜索優(yōu)先搜索樹如下圖所示:

對(duì)上圖的分析(Analysis):

  • A1)深度優(yōu)先生成森林中虛線箭頭是一些(v, w)邊, 其中的w 在考察時(shí)已經(jīng)做了標(biāo)記;
  • A2)我們看到,存在三種類型的邊并不通向新頂點(diǎn):
    • A2.1)背向邊:如(A,B) 和 (I,H);
    • A2.2)前向邊:如(C,D) 和 (C,E), 它們從樹的一個(gè)節(jié)點(diǎn)通向一個(gè)后裔;
    • A2.3)交叉邊:如(F,C)和(G,F), 它們把不直接相關(guān)的兩個(gè)樹節(jié)點(diǎn)連接起來(lái);
  • A3)深度優(yōu)先搜索森林一般通過(guò)吧一些子節(jié)點(diǎn)和一些新的樹從左到右添加到森林中形成。 在以這種方式構(gòu)成的有向圖的深度優(yōu)先搜索中,交叉邊總是從右到左進(jìn)行的;

1.4)深度優(yōu)先搜索(DFS)的一個(gè)用途是: 檢測(cè)一個(gè)有向圖是否是無(wú)圈圖;

  • 4.1) 法則如下: 一個(gè)有向圖是無(wú)圈圖當(dāng)且僅當(dāng)它沒(méi)有背向邊;(上面的圖有背向邊, 因此它不是無(wú)圈圖)
  • 4.2)拓?fù)渑判蛞部梢杂脕?lái)確定一個(gè)圖是否是無(wú)圈圖。進(jìn)行拓?fù)渑判虻牧硪环N方法是通過(guò)深度優(yōu)先生成森林的后序遍歷給頂點(diǎn)指定拓?fù)渚幪?hào)N, N-1, ..., 1; 只要圖是無(wú)圈的,這種排序就是一致的;

【2】source code + printing results(此處的dfs是對(duì)原始dfs修改而成的,與原始的dfs不同,但idea一樣)

2.1)download source code:  https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter9/p248_dfs_directed_graph
2.2)source code at a glance:(for complete code , please click the given link above)

void dfs(Vertex vertex, int depth) {int i;int visitFlag;AdjTable temp;Vertex adjVertex; //printf("\n\t visited[%c] = 1 ", flag[vertex]);visited[vertex] = 1; // update visited status of vertexvertexIndex[vertex] = counter++; // number the vertex with countertemp = adj[vertex]; visitFlag = 0; while(temp->next){ adjVertex = temp->next->vertex; if(visited[adjVertex]) // judge whether the adjVertes was visited before {if(vertexIndex[vertex] > vertexIndex[adjVertex] && parent[vertex] != adjVertex) {parent[adjVertex] = vertex; // building back side, attention of condition of building back side above// just for printing effectfor(i = 0; i < depth; i++) printf(" ");printf(" v[%c]->v[%c] (backside) \n", flag[vertex], flag[adjVertex]);} }//if(!visited[adjVertex])else{if(vertex == start)visitFlag = 1;parent[adjVertex] = vertex;// just for printing effectfor(i = 0; i < depth; i++) printf(" "); printf(" v[%c]->v[%c] (building edge) \n", flag[vertex], flag[adjVertex]);dfs(adjVertex, depth+1);}if(vertex == start && visitFlag) //conducingt dfs for only one adjoining vertex in the given graphbreak; temp = temp->next; } }

2.3)printing results(第二張圖是對(duì)第一張圖的補(bǔ)充,我最后添加了 dfsPathSet 方法打印出上述dfs遍歷路徑所產(chǎn)生的集合):

轉(zhuǎn)載于:https://www.cnblogs.com/pacoson/p/4990616.html

總結(jié)

以上是生活随笔為你收集整理的DFS应用——遍历有向图+判断有向图是否有圈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。