資料結構學習(C++)——圖【2】(DFS和BFS) (轉)
對於非線性的結構,遍歷都會首先成為一個問題。和二叉樹的遍歷一樣,圖也有深度優先搜尋(DFS)和廣度優先搜尋(BFS)兩種。不同的是,圖中每個頂點沒有了祖先和子孫的關係,因此,前序、中序、後序不再有意義了。仿照二叉樹的遍歷,很容易就能完成DFS和BFS,只是要注意圖中可能有迴路,因此,必須對訪問過的頂點做標記。
最基本的有向帶權網
#ifndef Graph_H
#define Graph_H
:namespace prefix = o ns = "urn:schemas--com::office" />
#include
#include
using namespace std;
#include "Graphmem.h"
template
classwork
{
public:
Network() {}
Network(dist maxdist) { data.NoEdge = maxdist; }
work() {}
bool insertV(name v) { return data.insertV(v); }
bool insertE(name v1, name v2, dist cost) { return data.insertE(v1, v2, cost); }
name& getV(int n) { return data.getV(n); }
int nextV(int m, int n = -1) { return data.nextV(m, n); }
int vNum() { return data.vNum; }
int eNum() { return data.eNum; }
protected:
bool* visited;
static void print(name v) { cout << v; }
private:
mem data;
};
#endif
你可以看到,這是在以mem方式儲存的data上面加了一層外殼。在圖這裡,邏輯上分有向、無向,帶權、不帶權;儲存結構上有鄰接矩陣和鄰接表。也就是說分開來有8個類。為了最大限度的複用程式碼,繼承關係就非常複雜了。但是,多重繼承是件很討厭的事,什麼覆蓋啊,還有什麼虛擬繼承,我可不想花大量篇幅講語言特性。於是,我將儲存方式作為第三個模板引數,這樣一來就省得涉及虛擬繼承了,只是這樣一來這個Network的例項化就很麻煩了,不過這可以透過typedef或者外殼類來解決,我就不寫了。反正只是為了讓大家明白,真正要用的時候,最好是寫專門的類,比如無向無權鄰接矩陣圖,不要搞的繼承關係亂七八糟。
DFS和BFS的實現
public:
void DFS(void(*visit)(name v) = print)
{
visited = new bool[vNum()];
for (int i = 0; i < vNum(); i++) visited[i] = false;
DFS(0, visit);
delete []visited;
}
protected:
void DFS(int i, void(*visit)(name v) = print)
{
visit(getV(i)); visited[i] = true;
for (int n = nextV(i); n != -1; n = nextV(i, n))
if (!visited[n]) DFS(n, visit);
}
public:
void BFS(int i = 0, void(*visit)(name v) = print)//n沒有越界檢查
{
visited = new bool[vNum()]; queue
for (n = 0; n < vNum(); n++) visited[n] = false;
visited[i] = true;
while (i != -1)//這個判斷可能是無用的
{
visit(getV(i));
for (n = nextV(i); n != -1; n = nextV(i, n))
if (!visited[n]) { a.push(n); visited[n] = true; }
if (a.empty()) break;
i = a.front(); a.pop();
}
delete []visited;
}
DFS和BFS很難寫得像樹的遍歷方法那麼通用,這在後面就會看到,雖然我們使用了DFS和BFS的思想,但是上面的函式卻不能直接使用。因為樹的資訊主要在節點上,而圖的邊上還有資訊。
測試
#include
using namespace std;
#include "Graph.h"
int main()
{
Network
a.insertV('A'); a.insertV('B');
a.insertV('C'); a.insertV('D');
a.insertE('A', 'B', 1); a.insertE('A', 'C', 2);
a.insertE('B', 'D', 3);
cout << "DFS: "; a.DFS(); cout << endl;
cout << "BFS: "; a.BFS(); cout << endl;
return 0;
}
老實說,這個類用起來真的不是很方便。不過能說明問題就好。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-982214/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料結構學習(C++)——圖(總結) (轉)資料結構C++
- 資料結構學習(C++)——遞迴【2】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(3) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【2】(4) (轉)資料結構C++遞迴
- 資料結構學習(C++)——遞迴【3】(2) (轉)資料結構C++遞迴
- 資料結構學習(C++)——圖【3】(無向圖)(上) (轉)資料結構C++
- 資料結構學習(C++)——圖【3】(無向圖)(下) (轉)資料結構C++
- 資料結構學習(C++)——序言 (轉)資料結構C++
- 資料結構學習(C++)——圖【4】(最短路徑) (轉)資料結構C++
- 資料結構學習(C++)——二叉樹【2】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——樹(總結) (轉)資料結構C++
- 資料結構學習(C++)——圖【1】(基本儲存方法) (轉)資料結構C++
- 資料結構學習(C++)續——排序【2】插入排序 (轉)資料結構C++排序
- 【資料結構與演算法】自己動手實現圖的BFS和DFS(附完整原始碼)資料結構演算法原始碼
- 資料結構學習(C++)——圖【5】活動網路(AOV、AOE) (轉)資料結構C++
- 資料結構學習(C++)——線性鏈式結構總結(代後記)【2】 (轉)資料結構C++
- 資料結構學習(C++)——遞迴【1】 (轉)資料結構C++遞迴
- 資料結構學習(C++)——迴圈連結串列 (轉)資料結構C++
- 資料結構學習(C++)——雙向連結串列 (轉)資料結構C++
- 資料結構學習(C++)——稀疏矩陣(十字連結串列【2】) (轉)資料結構C++矩陣
- 資料結構學習(c++)——二叉樹 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——遞迴【3】(1) (轉)資料結構C++遞迴
- 資料結構學習(C++)——棧和佇列(定義和實現) (轉)資料結構C++佇列
- 深度DFS 和 廣度BFS搜尋演算法學習演算法
- 資料結構學習總結--圖資料結構
- C++資料結構和pb資料結構的轉換C++資料結構
- 【資料結構與演算法筆記04】對圖搜尋策略的一些思考(包括DFS和BFS)資料結構演算法筆記
- 學習資料結構 - 深度優先搜尋 DFS 記錄資料結構
- 資料結構學習(C++)續——排序【3】交換排序 (轉)資料結構C++排序
- 資料結構學習(C++)——二叉樹【3】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——二叉樹【1】 (轉)資料結構C++二叉樹
- 資料結構學習(C++)——棧應用(表示式求值) (轉)資料結構C++
- 資料結構學習(C++)續——排序【1】測試程式 (轉)資料結構C++排序
- 資料結構學習(C++)續——排序【6】內部排序總結 (轉)資料結構C++排序
- 資料結構學習(C++)——單連結串列應用(一元多項式【2】) (轉)資料結構C++
- 聊聊演算法——BFS和DFS演算法
- 資料結構學習(C++)——線性鏈式結構總結(代後記)【1】 (轉)資料結構C++