天天看點

圖的存儲與周遊C++實作

設點數為n,邊數為m

方法:使用一個二維數組 adj 來存邊,其中 adj[u][v] 為 1 表示存在 u到 v的邊,為 0 表示不存在。如果是帶邊權的圖,可以在 adj[u][v] 中存儲u到v的邊的邊權。

複雜度:

查詢是否存在某條邊:\(O(1)\)

周遊一個點的所有出邊:\(O(n)\)

周遊整張圖:\(O(n^2)\)

空間複雜度:\(O(n^2)\)

方法:使用一個支援動态增加元素的資料結構構成的數組,如 vector< int> adj[n + 1] 來存邊,其中 adj[u] 存儲的是點u的所有出邊的相關資訊(終點、邊權等);

查詢是否存在u到v的邊:\(O(d^+(u))\)(如果事先進行了排序就可以使用二分查找做到\(O(log(d^+(u)))\) )。

周遊點u的所有出邊:\(O(d^+(u))\)。

周遊整張圖:O(n+m)。

空間複雜度:O(m)。

方法:使用一個數組來存邊,數組中的每個元素都包含一條邊的起點與終點(帶邊權的圖還包含邊權)。(或者使用多個數組分别存起點,終點和邊權。)

查詢是否存在某條邊:\(O(m)\)。

周遊一個點的所有出邊:\(O(m)\)。

周遊整張圖:\(O(nm)\)。

空間複雜度:\(O(m)\)。

由于直接存邊的周遊效率低下,一般不用于周遊圖。在Kruskal算法 中,由于需要将邊按邊權排序,需要直接存邊

方法:本質是用數組模拟連結清單,主要有兩個數組

複雜度:

代碼闆子:

基于上述的鍊式前向星實作

每次都嘗試通路同一層的節點。 如果同一層都通路完了,再通路下一層。這樣做BFS 算法找到的路徑是從起點開始的最短合法路徑。換言之,這條路所包含的邊數最小。在 BFS 結束時,每個節點都是通過從起點到該點的最短路徑通路的。

基于上述的鍊式前向星實作:

😄

❤️

祝看到這裡的你生活愉快,謝謝