【學習筆記----數據結構17-圖的十字鏈表】

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

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

我們重新定義頂點表結構

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

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

重新定義了邊表結點結構

其中

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

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

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

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

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

 

如圖

頂點依然是存入一個一維數組{v0,v1,v2,v3},實線箭頭指針的圖標完全與前面提到的鄰接表相同。就以頂點v0來說,firstout指向的是出邊表中的第一個結點v3。所以v0邊表結點的headvex=3,而tailvex其實就是當前頂點v0的下標0,由於v0只有一個出邊頂點,所以headlinktaillink都是空的。

我們重點需要來解釋虛線箭頭的含義,它其實就是此圖的逆鄰接表的表示。對於v0來說,它有兩個頂點v1v2的入邊。因此v0firstin指向頂點v1的邊表結點中headvex0的結點①。接着由入邊結點的headlink指向下一個入邊頂點v2,如圖②

對於頂點v1,它有一個入邊頂點v2,所以它的firstin指向頂點v2的邊表結點中headvex1的結點,如圖中的③。

firstin 指向headvex相同的,用的是headlink

firstout指向tailvex相同的,用的是taillink

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

鄰接多重表

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

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

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

重新定義邊表結構:

其中ivexjvex是與某條邊依附的兩個頂點在頂點表中的下標。ilink指向依附頂點ivex的下條邊,jlink指向依附頂點的下一條邊。這就是鄰接多重表結構

我們來看結構示意圖的繪製過程,理解了它是如何連線的,也就是理解鄰接多重表構造原理了。如下圖,左圖告訴我們它有4個頂點和5條邊,顯然我們就應該先將4個頂點和5條邊的邊表結點畫出來。由是無向圖,所以ivex0jvex1還是反過來都是無所謂的,不過爲了繪圖方便,都將ivex值設置得與一旁的頂點下標相同

首先連線①②③④就是將頂點的firstedge指向一條邊,頂點下標要與ivex的值相同,這很好理解,接着,由於頂點v0的(v0,v1)的鄰邊有(v0,v3)(v0,v2)。因此⑤⑥的連線就是滿足指向下一條依附於頂點v0的邊的目標,注意ilink指向的結點的jvex一定要和它本身的ivex值相同。同樣道理

連線⑦就是指(v1,v0)這條邊,它是相當於頂點v1指向(v1,v2)邊後的下一條。v2有三條邊依附,所以在v3之後就有⑧⑨。連線⑩的就是頂點v3在連線④之後的下條邊。

鄰接多重表與鄰接表的差別,僅僅是在於同一條邊在鄰接表中用兩個結點表示,而在鄰接多重表中只有一個結點。這樣對邊的操作就方便多了,若要刪除左圖的(v0,v2)這條邊,只要右圖的⑥⑨的鏈接指向改爲^即可。

邊集數組

邊集數組是由兩個一維數組構成。一個是存儲頂點的信息;另一個是存儲邊信息,這個邊數組每個數據元素由一條邊的起點下標(begin)、終點下標(end)和權(weight)組成。

在邊集數組中要查找一個頂點的度需要掃描整個數組,效率並不高。因此它更適合對邊依次時行處理的操作,而不適合對頂點相關的操作。回會學習一種克魯斯卡爾算法。

 

數據結構如下

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章