圖的存儲(chǔ)方式有兩種:鄰接矩陣和鄰接表。
鄰接矩陣
設(shè)圖G(V,E)的頂點(diǎn)標(biāo)號(hào)為0,1荠雕,...,N - 1驶赏,那么可以令二維數(shù)組G[N][N]的兩維分別表示圖的頂點(diǎn)標(biāo)號(hào)炸卑,即如果G[i][j]為1,則說(shuō)明頂點(diǎn)i和頂點(diǎn)j之間有邊煤傍;如果G[i][j]為0盖文,則說(shuō)明頂點(diǎn)i和頂點(diǎn)j之間不存在邊,而這個(gè)二維數(shù)組G[][]則被稱為鄰接矩陣蚯姆。另外五续,如果存在邊權(quán),則可以令G[i][j]存放邊權(quán)蒋失,對(duì)不存在的邊可以設(shè)邊權(quán)為0返帕、1或是一個(gè)很大的數(shù)。
鄰接矩陣比較好些篙挽,但是由于需要開(kāi)一個(gè)二維數(shù)組荆萤,如果頂點(diǎn)數(shù)目太大,便可能超過(guò)題目限制的內(nèi)存。因此鄰接矩陣只適用于定點(diǎn)數(shù)目不太大的(一般不超過(guò)1000)題目
鄰接表
設(shè)圖G(V,E)的頂點(diǎn)編號(hào)為0链韭,1偏竟,...,N - 1敞峭,每個(gè)頂點(diǎn)都可能有若干條出邊踊谋,如果把同一個(gè)頂點(diǎn)的所有出邊放在一個(gè)列表中,那么N個(gè)頂點(diǎn)就會(huì)有N個(gè)列表(沒(méi)有出邊旋讹,則對(duì)應(yīng)空表)殖蚕,這N個(gè)列表被稱為圖G的鄰接表,即為Adj[N]沉迹,其中Adj[i]存放頂點(diǎn)i的所有出邊組成的列表睦疫,這樣Adj[0],Adj[1]鞭呕,...蛤育,Adj[N - 1]就分別都是一個(gè)列表,列表可以用鏈表實(shí)現(xiàn)葫松,每個(gè)結(jié)點(diǎn)存放一條邊的信息(邊的終點(diǎn)編號(hào)瓦糕、邊權(quán))
在此介紹一種更為簡(jiǎn)單的工具來(lái)實(shí)現(xiàn)鄰接表:vector
由于vector有變長(zhǎng)數(shù)組之稱,因此可以開(kāi)一個(gè)vector數(shù)組Adj[N]腋么,其中N為頂點(diǎn)個(gè)數(shù)咕娄。這樣每個(gè)Adj[i]就都是一個(gè)變長(zhǎng)數(shù)組vector,使得存儲(chǔ)空間只與圖的邊數(shù)有關(guān)党晋。
如只存放每條邊的終點(diǎn)編號(hào)谭胚,而不存放邊權(quán)徐块,則vector中元素類型可以直接定義為int型
vector<int> Adj[N];
如添加一條從1號(hào)頂點(diǎn)到達(dá)3號(hào)頂點(diǎn)的有向邊未玻,只需要在Adj[1]中添加終點(diǎn)編號(hào)3即可
Adj[1].push_back(3);
如需要同時(shí)存放邊的終點(diǎn)編號(hào)和邊權(quán),那么可以建立結(jié)構(gòu)體Node胡控,用來(lái)存放每條邊的終點(diǎn)編號(hào)和邊權(quán)
struct Node {
int v;
int w;
}
vector<Node> Adj[N];
如添加從1號(hào)到達(dá)3號(hào)頂點(diǎn)的有向邊扳剿,邊權(quán)為4.
Node temp;
temp.v = 3;
temp.v = 4;
Adj[1].push_back(temp);
更快的做法是定義結(jié)構(gòu)體Node的構(gòu)造函數(shù)
struct Node {
int v, w;
Node(int _v, _w) : v(_v), w(_w) {}
}
這樣就能不定義臨時(shí)變量來(lái)實(shí)現(xiàn)加邊操作
Adj[1].push_back(Node(3, 4));
如頂點(diǎn)數(shù)較大(在1000以上)用鄰接表來(lái)存儲(chǔ)圖比較合適