圖是一種非線性表數據結構。
圖中的元素我們就叫作頂點(vertex)。
一個頂點可以與任意其他頂點建立連接關係,這種建立的關係叫作邊(edge)。
跟頂點相連接的邊的條數,叫作頂點的度(degree)。
無向圖
邊沒有方向的圖就叫作“無向圖”。
有向圖
邊有方向的圖叫作“有向圖”。
有向圖中,把度分爲入度(In-degree)和出度(Out-degree)。
頂點的入度,表示有多少條邊指向這個頂點;
頂點的出度,表示有多少條邊是以這個頂點爲起點指向其他頂點。
帶權圖
帶權圖中,每條邊都有一個權重 (weight),可以通過這個權重來表示 QQ 好友間的親密度。
存儲方法
鄰接矩陣 Adjacency Matrix
鄰接矩陣的底層依賴一個二維數組,
- 無向圖
如果頂點 i 與頂點 j 之間有邊,我們就 將 A[i][j] 和 A[j][i] 標記爲 1; - 有向圖
如果頂點 i 到頂點 j 之間,有一條箭頭從頂點 i 指向頂點 j 的邊,就將 A[i][j] 標記爲 1;
如果有一條箭頭從頂點 j 指向頂點 i 的 邊,就將 A[j][i] 標記爲 1; - 帶權圖,數組中就存儲相應的權重。
優點: 簡單、直觀、獲取關係時高效、運算方便
缺點: 浪費空間
首先,無向圖中,如果 A[i][j] 等於 1,那 A[j][i] 也肯定等於 1,對角線上下兩部分相等,浪費一半空間;
其次,存儲的矩陣大都是稀疏矩陣,比如微信有好幾億的用戶,對應到圖上就是好幾億的頂點。但矩陣中絕大部分都是0。
鄰接表 Adjacency List
結構類似於散列表,每個頂點對應一條鏈表,鏈表中存儲的是與這個頂點相連接的其他頂點。
對於無向圖類似,不過每個頂點的鏈表中存儲的,是跟這個頂點有邊相連的頂點。
這種方法節省空間,但是使用起來就比較耗時間。
若想判斷是否存在一條從頂點 2 到頂點 4 的邊,就要遍歷 頂點 2 對應的那條鏈表,看鏈表中是否存在頂點 4。
可以將鏈表改成紅黑樹或跳錶,以增加查找速度。
逆鄰接表
以微博關注爲例,
使用鄰接表查找某個用戶關注了哪些用戶容易(某個頂點指向哪些其他頂點),
但是如果想知道某個用戶都被哪些用戶關注了,也就是用戶的粉絲列表,是非常困難的。
這時,需要一個逆鄰接表,來存儲指向這個頂點的頂點。
本文是極客時間王爭 數據結構與算法 課程的筆記,推薦此課,喜歡可以購買課程。