簡體   English   中英

圖形內存實現

[英]Graph memory implementation

通常用於在內存中表示圖形的兩種方式是使用鄰接列表或鄰接矩陣。 使用指向鏈表的指針數組實現鄰接列表。 有沒有什么理由比使用矢量矢量更快? 我覺得它應該使搜索和遍歷更快,因為回溯會更簡單。

鏈接鄰接的向量是最受歡迎的教科書模因,在實踐中有許多變化。 當然你可以使用矢量矢量。 有什么區別?

一個是鏈接(無論如何都是雙鏈接)允許在恆定時間內輕松添加和刪除邊。 這顯然只有在邊緣集縮小和增長時才是重要的。 對於邊緣矢量,任何單獨的操作都可能需要O(k),其中k是入射邊緣計數。

注意:如果鄰接列表中的邊緣順序對於您的應用程序而言並不重要,則可以使用向量輕松獲得O(1)刪除。 只需將最后一個元素復制到要刪除的元素的位置,然后刪除最后一個元素! 唉,當鄰接的順序很重要時,有很多情況(例如,你擔心嵌入飛機的地方)。

即使必須維持訂單,您也可以安排復制成本以攤銷到許多操作的每個操作的平均值O(1)。 仍然在某些應用中,這還不夠好,並且它需要“刪除”標記(保留頂點數量就足夠了),只有當標記刪除的數量是向量的固定部分時才執行壓縮。 代碼很繁瑣,在所有操作中檢查已刪除的節點會增加開銷。

另一個區別是開銷空間。 鄰接列表節點非常小:只是一個節點號。 雙鏈路可能需要4倍於數字本身的空間(如果數字是32位,兩個指針都是64)。 對於非常大的圖形,400%的空間開銷並不是那么好。

最后,經常長時間編輯的鏈接數據結構很容易導致高度不連續的內存訪問。 與通過向量的線性訪問相比,這降低了緩存性能。 所以這里的矢量獲勝。

在大多數應用中,差異並不值得擔心。 然后,巨大的圖形是現代世界的方式。

正如其他人所說的那樣,為鄰接使用通用的List容器是個好主意,可以通過鏈接節點或節點向量快速實現。 例如,在Java中,您將使用List和實現/ profile同時使用LinkedListArrayList來查看哪種方法最適合您的應用程序。 NB ArrayList在每次remove壓縮數組。 沒有攤銷如上所述,雖然add s 攤銷。

還有其他變化:假設您有一個非常密集的圖形,其中經常需要搜索具有特定標簽的一個給定節點的所有邊緣。 然后你想要鄰接的地圖 ,其中鍵是邊緣標簽。 當然,地圖可以是哈希或樹木或跳過列表或任何你喜歡的。

名單還在繼續。 如何實現有效的頂點刪除? 正如您所料,這里也有替代品,每種都有優點和缺點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM