為什麼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 ,使得大量的二維陣列陣列空間被浪費。
使用鄰接表(連結串列)儲存
如上面的 圖,對其使用 連結串列 來儲存,略像雜湊表,每行都是一個節點,每列也只儲存這個節點的所有 出度。
兩種儲存方式的比較
我們要根據不同的情況來決定不同的儲存資料結構:
- 陣列:浪費空間,但是速度快。適合處理資料不大的,只要資料不大,優先選用陣列
- 連結串列:節省空間,但是速度慢。資料大的時候,使用鄰接表(連結串列來儲存)
推薦閱讀:
我偷偷挖了一條網路隧道,差點被公司啟用
每天三分鐘玩轉Git(完結)
promethus與監控系統
點此瞭解並加入程式設計大隊,程式設計大隊,nb !!