1. 程式人生 > >為什麼QQ能幫你找到失散多年的兄弟?----圖論

為什麼QQ能幫你找到失散多年的兄弟?----圖論

程式設計三分鐘的第 44 篇原創文章

為什麼qq裡“可能認識的人”功能推薦的如此精準?
為什麼兩個沒有什麼聯絡的朋友會相互認識?
一切的背後到底是道德的淪喪,還是人性的扭曲 ? 讓我們走進圖的內心世界!

什麼是圖?

微信好友之間的關係像一張巨大的網路,朋友的朋友可能是自己的朋友,所以用一種叫 圖 的資料結構儲存起來,元素和元素之間都可能發生關係。

下面要開始乾貨了!非戰鬥成員請撤離,圖有兩種有向圖和無向圖,唯一的區別就是有木有箭頭,是不是看起來很像關係網。


來說說它的細節

圖上的東西全都有名字,圓圈 圈著字母叫 頂點,是最基本的組成元素。

連線各個頂點的線就是 邊,圖 可以沒有 邊,但是不能沒有 頂點 。連線某個頂點的邊數量叫做這個頂點的 度。比如上圖中的 C 有三個度。

有向圖多一個概念,那就是出度,入度。比如 C 頂點,有兩個箭頭指向自己,一個箭頭指出來,就是兩 入度,一 出度。

如何儲存圖

經過我精彩的表達,想必你肯定知道了圖的基本概念,作為一個技術人員,刨根問底才是我們的特色。
有沒有想過長的這麼瘋狂的一個數據結構,他是怎麼存的?

因為要表現出來每個頂點都有可能指向其他頂點,所以有兩種常見的儲存方式,二維陣列 和 鄰接表。

使用鄰接矩陣(二維陣列)儲存

下面就是非常明顯的二維陣列儲存圖的例子。

上圖是 8 * 8 的二維陣列,豎著和橫著都是各個 頂點,比如 開發 、設計 、工程 都是頂點。
每一行都代表當前這個人對其他 8 個人的看法(包括自己),在圖裡就只有 有關係 和 沒關係 兩種看法而已。

例如上圖, A - G 共 7 個頂點,所以需要 7 * 7 的二維陣列。
橫座標代表著當前的節點,縱座標代表當前節點和其他節點的關係,加入當前節點有 出度,那麼當前的值就為 1 ,入度不管,拆解如下:

- A B C D E F G
A 0 1 0 0 0 0 0
B 0 0 1 0 1 1 0
C 0 0 0 0 1 0 0
D 0 0 1 0 0 0 0
E 0 1 0 1 0 0 0
F 0 0 0 0 0 0 1
G 0 0 0 0 0 0 0

頭髮少叫頭髮稀疏,1 少就叫 稀疏矩陣,指的就是圖的各個頂點之間的聯絡很少,存了沒意義的 0 ,使得大量的二維陣列陣列空間被浪費。

使用鄰接表(連結串列)儲存


如上面的 圖,對其使用 連結串列 來儲存,略像雜湊表,每行都是一個節點,每列也只儲存這個節點的所有 出度。

兩種儲存方式的比較

我們要根據不同的情況來決定不同的儲存資料結構:

  1. 陣列:浪費空間,但是速度快。適合處理資料不大的,只要資料不大,優先選用陣列
  2. 連結串列:節省空間,但是速度慢。資料大的時候,使用鄰接表(連結串列來儲存)

推薦閱讀:

我偷偷挖了一條網路隧道,差點被公司啟用

每天三分鐘玩轉Git(完結)

promethus與監控系統


點此瞭解並加入程式設計大隊,程式設計大隊,nb !!