數據結構——關於圖的存儲中十字鏈表和鄰接多重表的理解和思考


有向圖的十字鏈表

對於有向圖來說,鄰接表是有缺陷的,關心了出度問題,想了解入度就必須要遍歷整個圖才能知道,反之,逆鄰接表解決了入度的情況。

把鄰接表與逆鄰接表結合起來,即有向圖的一種存儲方法十字鏈表(Orthogonal   List)。

我們重新定義頂點表結構

firstin表示入邊表頭指針,指向該頂點的入邊表中第一個結點;

firstout表示出邊表頭指針,指向該頂點的出邊表中第一個結點;

重新定義了邊表結點結構

其中

tailvex是指弧起點在頂點的下標,

headvex是指弧終點在頂點表中的下標,

headlink是指入邊表指針域,指向終點相同的一下條邊

taillink是指出邊表指針域,指向起點相同的下一條邊。

如果是網,還可以再增加一個weight域來存儲權值。

 

如圖對於這樣的一個有向圖,構建如下的十字鏈表

 

 

對於十字鏈表的一些認識:

1.表頭結點即頂點結點,與鄰接表一樣是順序存儲。

2.對於每個頂點結點之后是與之相關聯的弧結點(該弧結點中存有弧頭、弧尾),而鄰接表則是一些與頂點結點相連接的點。

3.從每個頂點結點開始有兩條鏈表,一條是以該頂點結點為弧頭的鏈表,一條是以該頂點結點為弧尾的鏈表。

4.對於其中的每一條鏈表必然是從頂點結點開始,直到與之相關的弧結點鏈域headlink和taillink為空是結束,構成一條完整的鏈表。

十字鏈表存儲結構:

typedef struct ArcBox   // 弧的結構表示
{
    int tailvex, headvex;
    InfoType  *info;
    struct ArcBox  *hlink, *tlink;
} VexNode;
typedef struct VexNode   // 頂點的結構表示
{
    VertexType  data;
    ArcBox  *firstin, *firstout;
} VexNode;
typedef
struct { VexNode xlist[MAX_VERTEX_NUM];// 頂點結點(表頭向量) int vexnum, arcnum;//有向圖的當前頂點數和弧數 } OLGraph;

十字鏈表的好處就是因為把鄰接表和逆鄰接表整合在一起,這樣既容易找到vi為尾的弧,也容易打到以vi為頭的弧,因而容易求得頂點的出度和入度。而且它除了結構復雜一點燃上,其實創建圖的算法的時間復雜度與鄰接表相同,因此,在有向圖的應用中,十字鏈表是非常好的數據結構模型。

 

無向圖的鄰接多重表

 

對於無向圖的邊操作,如下圖要刪除(v0,v2)這條邊要做

 

需要對鄰接表結構中右邊表的陰影兩個結點進行刪除操作,顯然比較煩瑣

因此,我們也仿照十字鏈表的方式對邊表結構進行一些改造,也許就可避免剛才的問題。

重新定義邊表結構:

 

其中mark是標志域,用於標記該條邊是否訪問過。ivexjvex是與某條邊依附的兩個頂點在頂點表中的下標。ilink指向依附頂點ivex的下條邊,jlink指向依附頂點的下一條邊。這就是鄰接多重表結構

 對於頂點結構不變,也是用一個結點表示,由存儲與該結點信息相關的域date和指示第一條依附於該結點的邊的域firstedge構成。

 

我們來看結構示意圖的繪制過程,理解了它是如何連線的,也就是理解鄰接多重表構造原理了。

 

 

 

對於鄰接多重表的一些認識:

1.表頭結點即頂點結點,與鄰接表一樣是順序存儲。

2.對於每個頂點結點之后是與之相關聯的邊結點(與該頂點結點相連的邊),而鄰接表則是一些與頂點結點相連接的點。

3.從每個頂點結點開始有一條鏈表,這條鏈表將所有與該頂點相連的邊都連接了起來。

4.鄰接多重表中邊結點的個數就是無向圖中邊的數量,又因為無向圖中的邊必然連接兩個頂點,所以便邊結點結構中的ilink和jlink會連接兩個不同的鏈表。

 

鄰接多重表的存儲結構:

typedef struct Ebox
{
    VisitIf  mark;      // 訪問標記
    int ivex, jvex;//該邊依附的兩個頂點的位置
    struct EBox  *ilink, *jlink;
    InfoType *info;          // 該邊信息指針
} EBox;
typedef struct VexBox
{
    VertexType  data;
    EBox  *firstedge; // 指向第一條依附該頂點的邊
} VexBox;
typedef struct    // 鄰接多重表
{
    VexBox  adjmulist[MAX_VERTEX_NUM];
    int   vexnum, edgenum;
} AMLGraph;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM