2.深度優先搜索
爲了訪問一個頂點,咱們將它標記爲已經訪問過,而後遞歸的訪問全部與子鄰接的而且還沒有標記的頂點,這就是深度優先搜索(DFS),DFS經常使用於解決路徑問題。
好比下面的連通圖,咱們從頂點0開始對圖進行探索html
下面這個圖顯示了DFS處理時的遞歸調用樹。算法
DFS能夠解決的問題:
1)環檢測:一個圖中有環嗎?該圖是森林嗎?
2)簡單路徑:給定兩個頂點,是否存在一條鏈接他們的路徑
3)簡單連通性:不管什麼時候使用DFS,均可以在線性時間內肯定一個圖是否連通
4)頂點搜索:在給定頂點所在的同一個連通份量中有多少個頂點呢?函數
DFS算法的特色:
1)對於用鄰接矩陣表示的圖,其DFS須要的時間與V*V成正比
2)對於用鄰接表表示的圖,其DFS須要的時間與V+E成正比spa
1 //程序:連通份量的深度優先搜索 2 #include <vector> 3 template <class Graph> class cDFS 4 { 5 private: 6 int cnt;//記錄搜索順序的變量 7 const Graph& G; 8 vector<int> order;//保存每一個頂點被搜索的順序 9 void serachC(int v) 10 { 11 order[v]=cnt++; 12 typename Graph::adjIterator ite(G,v);//圖的迭代器,上一節有介紹過 13 for(int t=ite.begin();!ite.end();t=ite.next()) 14 if(order[t]==-1) serachC(t);//若是頂點未被標記,遞歸調用搜索函數 15 16 } 17 public: 18 cDFS(const Graph& g,int v=0):G(g),cnt(0),order(g.V(),-1){ 19 serachC(v); 20 } 21 int count() const{return cnt;}//返回圖的頂點數 22 int operator[](int v) const{return order[v];} 23 24 };
3.廣度優先搜索
假設但願找到一個圖中兩個特定頂點之間的一條最短路徑--鏈接這兩個頂點而且知足:在鏈接這兩個頂點的路徑中,不存在邊數筆它更少的其餘路徑,這裏咱們使用廣度優先搜索(BFS),在進行圖搜索時,會有多條邊能夠遍歷,可先選擇其中一條,並保存其餘邊留待後續處理,咱們這裏須要使用一個先進先出隊列,而後按下列步驟處理,直到隊列爲空:3d
1)從隊列中pop一個頂點
2)訪問該頂點,將由此頂點到未訪問頂點的全部邊放入隊列中code
1 //程序:廣度優先搜索單源最短路徑 2 #include <queue> 3 4 template <class Graph> class BFS 5 { 6 private: 7 const Graph& G; 8 vector<int> dist;//用來存儲每一個頂點和源點的距離 9 vector<int> path;//用來存儲每一個頂點的前一個頂點 10 void search(int s) 11 { 12 queue<int> q; 13 q.push(s); 14 while(!q.empty()) 15 { 16 int v=q.pop(); 17 typename Graph::adjIterator ite(G,v);//鄰接表迭代器 18 for(int w=ite.begin();!ite.end();w=ite.next()) 19 20 if(dist[w]==-1) 21 { 22 dist[w]=dist[v]+1; 23 path[w]=v; 24 q.push(w); 25 } 26 27 } 28 } 29 public: 30 BFS(const Graph& g,int s):G(g),dist(g.V(),-1),path(g.V(),0){search(s);} 31 int distance(int v) const{return dist[v];} 32 int path(int v) const{return path[v];} 33 34 };
在BFS中,頂點以其與起始頂點的距離爲順序進入和離開FIFO順序,以下圖所示:htm
在以s爲根的BFS樹中,對於其中任何一個節點w,從v到w的數路徑對應爲圖中從v到w的最短路徑,以下圖所示:blog
利用BFS能夠解決最短路徑,單源最短路徑和全源最短路徑的問題。遞歸
原文地址:http://lippiouyangonline.info/algorithm/2013/12/29/graph.html隊列