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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【数据结构】图的深度优先搜索

發(fā)布時(shí)間:2023/12/13 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据结构】图的深度优先搜索 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  圖的深度優(yōu)先搜索類似于樹的深度優(yōu)先搜索。不同的是,圖中可能包括循環(huán),即我們有可能重復(fù)訪問節(jié)點(diǎn)。為了避免訪問已經(jīng)訪問過的節(jié)點(diǎn),我們要使用一個(gè)布爾變量的數(shù)組。

  例如,在下圖中,我們從節(jié)點(diǎn)2開始訪問。當(dāng)訪問到節(jié)點(diǎn)0,我們尋找它的所有緊接節(jié)點(diǎn)。節(jié)點(diǎn)2也屬于節(jié)點(diǎn)0的鄰接節(jié)點(diǎn)。如果我們沒有標(biāo)記訪問的節(jié)點(diǎn),那么節(jié)點(diǎn)2 將會(huì)被重復(fù)訪問,這樣的話整個(gè)算法過程就不會(huì)停下來了。下圖的深度優(yōu)先搜索是2,0,1,3

  這種搜索算法所遵循的搜索策略是盡可能“深”地搜索一個(gè)圖。它的基本思想如下:首先訪問圖中某一起始頂點(diǎn)v,然后由v出發(fā),訪問與v鄰接且未被訪問的任一頂點(diǎn)w1,再訪問與w1鄰接且未被訪問的任一頂點(diǎn)w2,......重復(fù)上述過程。當(dāng)不能再繼續(xù)向下訪問時(shí),一次退回到最近被訪問的頂點(diǎn),若它還有鄰接頂點(diǎn)未被訪問過,則從該點(diǎn)開始繼續(xù)上述搜索過程,直到圖中所有頂點(diǎn)均被訪問過為止。

  舉個(gè)例子:

  

  上圖一幅無向圖。我們從A點(diǎn)開始遍歷,并假設(shè)左邊的節(jié)點(diǎn)先被訪問到。那么訪問順序是A,搜索A所有可訪問的鄰接節(jié)點(diǎn)并選擇B,然后訪問B,搜索B所有可訪問的鄰接節(jié)點(diǎn)并選擇D,然后訪問D,搜索D的所有可訪問的鄰接節(jié)點(diǎn)。由于D只有一個(gè)鄰接節(jié)點(diǎn)B,而B已經(jīng)被訪問過。所以回退到D的上級B(注意,不是訪問B,僅僅是回到上級)。然后再搜索B的所有可訪問的鄰接節(jié)點(diǎn),AD已經(jīng)被訪問過,所以訪問F。這個(gè)過程一直持續(xù)直到訪問過所有的節(jié)點(diǎn)。

  選擇可訪問鄰接節(jié)點(diǎn)的時(shí)候,可以使用我們自己定義的順序。比如訪問A的鄰接節(jié)點(diǎn)的時(shí)候,可以先訪問B,也可以先訪問E。可根據(jù)需求靈活調(diào)整。

?

下述代碼是深度優(yōu)先搜索的C++版本,有遞歸和迭代版本。圖的實(shí)現(xiàn)使用鄰接鏈表表示。STL的list被用來存儲(chǔ)鄰接節(jié)點(diǎn)。

#include<list> #include<iostream> using namespace std;class Graph {private:int V;list<int>* adj;void DfsUtil(int v, bool visited[]);public:Graph(int n); //No of vertices~Graph(); //Pointer to an array containing adjacency listsvoid addEdge(int v, int w); //function to add an edge to graphvoid Dfs(int s); //Dfs traversal of the vertices reachable from vvoid DfsIter(int s); };Graph::Graph(int v) {V = v;adj = new list<int>[V]; }Graph::~Graph() {delete []adj;adj = NULL; }void Graph::addEdge(int v, int w) {adj[v].push_back(w); //Add w to v's list }void Graph::Dfs(int s) {bool* visited = new bool[V];for (int i = 0; i < V; i++)visited[V] = false;DfsUtil(s, visited); }void Graph::DfsUtil(int v, bool visited[]) {//Mark the current node as the visited and print itvisited[v] = true;cout<<v<<" ";//Recur for all vertices adjacent to this vertexlist<int>::iterator i;for (i = adj[v].begin(); i != adj[v].end(); i++)if (!visited[*i])DfsUtil(*i, visited); }void Graph::DfsIter(int v) {bool* visited = new bool[V];for (int i = 0; i < V; i++)visited[i] = false;list<int> stack;stack.push_back(v);list<int>::iterator i;while (!stack.empty()) {v = stack.back();cout<<v<<" ";stack.pop_back();visited[v] = true;for(i = adj[v].begin(); i != adj[v].end(); i++)if (!visited[*i])stack.push_back(*i);} delete []visited; }int main() {// Create a graph given in the above diagramGraph g(4);g.addEdge(0, 1);g.addEdge(0, 2);g.addEdge(1, 2);g.addEdge(2, 0);g.addEdge(2, 3);g.addEdge(3, 3);cout << "Following is Depth First Traversal (starting from vertex 2) \n";g.DfsIter(2);return 0; }

?

輸出:

Following is Depth First Traversal (starting from vertex 2) 2 0 1 3

?

參考資料:

  1. http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/

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

總結(jié)

以上是生活随笔為你收集整理的【数据结构】图的深度优先搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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