資料結構:圖的表示

發表於2016-11-30

任何一本講到圖演算法的演算法書,都會講到圖的表示方法有兩種

1 鄰接矩陣 ,對於N個點的圖,需要N×N的矩陣表示點與點之間是否有邊的存在。這種表示法的缺點是浪費空間,尤其是對於N×N的矩陣是稀疏矩陣,即邊的數目遠遠小於N×N的時候,浪費了巨大的儲存空間

24774106_1362195546qm7q

2 鄰接連結串列,對於任何一個node A,外掛一個鄰接連結串列,如果存在 A->X這樣的邊,就將X鏈入連結串列。 這種表示方法的優點是節省空間,缺點是所有連結串列都存在的缺點,地址空間的不連續造成快取命中降低,效能有不如臨界矩陣這樣的陣列。

24774106_1362197565517r

一直以來,我也是覺得,魚和熊掌不可兼得,這是無可奈何的事情。直到我看到了一份比較完美的code。他有動態分配的陣列來存放鄰接節點。一起欣賞下這份程式碼吧。年前我第一次看到這份程式碼的時候,激動的我晚上半天睡不著覺。平時自己寫的程式碼,一板一眼,雖說功能無誤,總少了那麼幾分靈氣。看了C演算法,也算對圖的表示方法知道一些,卻寫不出這麼優美的程式碼。

我以前覺得,自己大量練習聯絡寫程式碼是學習程式設計的最好的方法,是最開但是看了這份程式碼後,覺得,學習前輩高人優秀的程式碼,是提高自己的一條捷徑,對我們這些普通的coder而言,我們看程式碼的時間是超過寫程式碼的時間的。閱讀前輩優秀程式碼,會更快的提升自己的程式設計能力。對於初學者尤其是這樣,這也是進入一個優秀的開發team的重要性,能更快的成長。

欣賞程式碼Yale大學前輩的程式碼吧。

這是一份PineWiki網站裡面提供的一份圖的表示的程式碼,實現的很優美吧?動態分配陣列,長度可以擴充套件,既不浪費空間,有不會帶來效能損失。

除此外,graph_foreach這種思想也很不錯啊。最近學習了一段時間的Lisp,這種傳遞函式作用到每一個元素上的方法,相當於Lisp中的mapcar,讓人不僅拍案叫絕,很容易就能擴充套件出很好的功能。(當然也不是完全沒瑕疵,比如realloc沒有判斷失敗的情景,白璧微瑕)

既然是圖的表示,我們當然很希望能夠看到視覺化的圖。我看Land of Lisp一書中,學到了Linux下的neato 命令。 Linux下有工具幫助生成圖的圖片,可以滿足我們視覺化的需求。

先看下測試程式碼。

我們這個測試程式基本測試了graph的API,同時利用graph_foreach函式的高效擴充套件性,輸出了dot檔案格式的檔案我們看下執行結果。

在我的Ubuntu下面用XDot可以看到test.dot已經是個圖形檔案了。圖形如下:

24774106_136214724653lb

當然了,我們也可以用 dot命令繪製出PNG格式的圖片來:

我們可以看到在當前目錄下產生了一個檔名為graph_test.png的PNG格式的圖片。開啟看下和上面的圖是一致的。我就不貼圖了。

對dot感興趣的筒子,可以繼續閱讀『dot 學習筆記』二. 記錄 Shell 的變遷

參考文獻:

1  Land of Lisp

2 PineWiki

3 演算法:C語言實現。

相關文章