1、前向星
前向星是以存儲邊的方式來存儲圖,先將邊讀入並存儲在連續的數組中,然后按照邊的起點進行排序,這樣數組中起點相等的邊就能夠在數組中進行連續訪問了。它的優點是實現簡單,容易理解,缺點是需要在所有邊都讀入完畢的情況下對所有邊進行一次排序,帶來了時間開銷,實用性也較差,只適合離線算法。
圖一-2-4展示了圖一-2-1的前向星表示法。


2、鏈式前向星(就是數組模擬鏈表)
鏈式前向星和鄰接表類似,也是鏈式結構和線性結構的結合,每個結點i都有一個鏈表,鏈表的所有數據是從i出發的所有邊的集合(對比鄰接表存的是頂點集合),邊的表示為一個四元組(u, v, w, next),其中(u, v)代表該條邊的有向頂點對,w代表邊上的權值,next指向下一條邊。
具體的,我們需要一個邊的結構體數組 edge[MAXM],MAXM表示邊的總數,所有邊都存儲在這個結構體數組中,並且用head[i]來指向 i 結點的第一條邊。
邊的結構體聲明如下:
struct EDGE {
int u, v, w, next;
EDGE() {}
EDGE(int _u, int _v, int _w, int _next) {
u = _u, v = _v, w = _w, next = _next;
}
}edge[MAXM];
int u, v, w, next;
EDGE() {}
EDGE(int _u, int _v, int _w, int _next) {
u = _u, v = _v, w = _w, next = _next;
}
}edge[MAXM];
初始化所有的head[i] = INF,當前邊總數 edgeCount = 0
每讀入一條邊,調用addEdge(u, v, w),具體函數的實現如下:
void addEdge(int u, int v, int w) {
edge[ edgeCount ] = EDGE(u, v, w, head[u]);
head[u] = edgeCount ++;
}
edge[ edgeCount ] = EDGE(u, v, w, head[u]);
head[u] = edgeCount ++;
}
這個函數的含義是每加入一條邊(u, v),就在原有的鏈表結構的首部插入這條邊,使得每次插入的時間復雜度為O(1),所以鏈表的邊的順序和讀入順序正好是逆序的。這種結構在無論是稠密的還是稀疏的圖上都有非常好的表現,空間上沒有浪費,時間上也是最小開銷。
調用的時候只要通過head[i]就能訪問到由 i 出發的第一條邊的編號,通過編號到edge數組進行索引可以得到邊的具體信息,然后根據這條邊的next域可以得到第二條邊的編號,以此類推,直到next域為INF(這里的INF即head數組初始化的那個值,一般取-1即可)。

