數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)(C++)——圖(DFS和BFS)
更新時間: 2007-05-25 10:17:18來源: 粵嵌教育瀏覽量:1389
對于非線性的結(jié)構(gòu),遍歷都會首先成為一個問題。和二叉樹的遍歷一樣,圖也有深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)兩種。不同的是,圖中每個頂點沒有了祖先和子孫的關(guān)系,因此,前序、中序、后序不再有意義了。仿照二叉樹的遍歷,很容易就能完成DFS和BFS,只是要注意圖中可能有回路,因此,必須對訪問過的頂點做標(biāo)記。
基本的有向帶權(quán)網(wǎng)
#ifndef Graph_H
#define Graph_H
#include
#include
using namespace std;
#include "Graphmem.h"
template
class Network
{
public:
Network() {}
Network(dist maxdist) { data.NoEdge = maxdist; }
~Network() {}
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上面加了一層外殼。在圖這里,邏輯上分有向、無向,帶權(quán)、不帶權(quán);儲存結(jié)構(gòu)上有鄰接矩陣和鄰接表。也就是說分開來有8個類。為了限度的復(fù)用代碼,繼承關(guān)系就非常復(fù)雜了。但是,多重繼承是件很討厭的事,什么覆蓋啊,還有什么虛擬繼承,我可不想花大量篇幅講語言特性。于是,我將儲存方式作為第三個模板參數(shù),這樣一來就省得涉及虛擬繼承了,只是這樣一來這個Network的實例化就很麻煩了,不過這可以通過typedef或者外殼類來解決,我就不寫了。反正只是為了讓大家明白,真正要用的時候,是寫專門的類,比如無向無權(quán)鄰接矩陣圖,不要搞的繼承關(guān)系亂七八糟。
DFS和BFS的實現(xiàn)
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 a; int n;
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函數(shù)很難寫得像樹的遍歷方法那么通用,這在后面就會看到,雖然我們使用了DFS和BFS的思想,但是上面的函數(shù)卻不能直接使用。因為樹的信息主要在節(jié)點上,而圖的邊上還有信息。
測試程序
#include
using namespace std;
#include "Graph.h"
int main()
{
Network > a;
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;
}
老實說,這個類用起來真的不是很方便。不過能說明問題就好。
推薦閱讀
- ·Linux字符設(shè)備驅(qū)動框架解析:file_operations的核心作用與實現(xiàn)
- ·廣東朝歌數(shù)碼科技股份有限公司專場招聘會
- ·深化產(chǎn)教融合,共筑技能人才培養(yǎng)新生態(tài) —— 廣州華立學(xué)院到訪粵嵌從化校區(qū)為深化產(chǎn)教
- ·校企合作新突破 | 粵嵌科技與三亞學(xué)院共探產(chǎn)教融合新路徑
- ·粵嵌科技入選國家級職業(yè)數(shù)字展館聯(lián)合建設(shè)單位,賦能計算機程序設(shè)計員高技能人才培養(yǎng)
- ·嵌入式實時操作系統(tǒng)的性能優(yōu)化與實現(xiàn)路徑
- ·校企攜手賦能教育!粵嵌科技助力海南科技職業(yè)大學(xué)探索 AGI 時代教學(xué)新范式
- ·嵌入式系統(tǒng)中的低功耗設(shè)計策略與實現(xiàn)路徑
- ·深圳市軒宇軟件開發(fā)有限公司專場招聘會
- ·嵌入式系統(tǒng)中的代碼空間優(yōu)化:策略與實踐