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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

【0】README

0.1) 本文總結于 數據結構與算法分析, 源代碼均為原創, 旨在 理解 “DFS應用——遍歷有向圖+判斷有向圖是否有圈” 的idea 并用源代碼加以實現 ;
0.2) 判斷有向圖是否有圈的rule—— 一個有向圖是無圈圖當且僅當它沒有背向邊,背向邊定義,參見: http://blog.csdn.net/pacosonswjtu/article/details/49967255 
0.3) 代碼最后還添加了打印dfs遍歷路徑所產生的集合, 對的,dfs 就應該這么玩,Bingo!


【1】有向圖相關

1.1)對有向圖進行DFS的idea:利用與無向圖相同的思路, 也可以通過深度優先搜索以線性時間遍歷有向圖。如果圖不是強連通的,那么從某個節點開始的DFS可能訪問不了所有的節點。在這種情況下, 我們在某個未作標記的節點處開始,反復執行DFS, 直到所有節點都被訪問到;
1.2)基于以上描述, 我們看個荔枝(這只是一種可能的case):

  • step1)從頂點B 任意開始深度優先搜索, 訪問頂點B, C, A, D, E;
  • step2)從頂點 F 任意開始DFS, 訪問頂點 F;
  • step3)從頂點 H 任意開始DFS, 訪問頂點 H, J, I;
  • step4)從頂點 G 任意開始DFS, 訪問頂點 G;

1.3)對于以上的DFS過程, 對應的搜索優先搜索樹如下圖所示:

對上圖的分析(Analysis):

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

1.4)深度優先搜索(DFS)的一個用途是: 檢測一個有向圖是否是無圈圖;

  • 4.1) 法則如下: 一個有向圖是無圈圖當且僅當它沒有背向邊;(上面的圖有背向邊, 因此它不是無圈圖)
  • 4.2)拓撲排序也可以用來確定一個圖是否是無圈圖。進行拓撲排序的另一種方法是通過深度優先生成森林的后序遍歷給頂點指定拓撲編號N, N-1, ..., 1; 只要圖是無圈的,這種排序就是一致的;

【2】source code + printing results(此處的dfs是對原始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(第二張圖是對第一張圖的補充,我最后添加了 dfsPathSet 方法打印出上述dfs遍歷路徑所產生的集合):

轉載于:https://www.cnblogs.com/pacoson/p/4990616.html

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。