【数据结构与算法】图
一:如何理解“圖”
1,圖和樹一樣都是非線性表數(shù)據(jù)結(jié)構(gòu),和樹不同的是圖是一種更加復(fù)雜的非線性表結(jié)構(gòu)
2,樹中的元素稱之為節(jié)點(diǎn),圖中的元素則稱之為頂點(diǎn)。
3,頂點(diǎn)可以與任意其他頂點(diǎn)建立關(guān)聯(lián),這種建立的關(guān)系叫做邊,與頂點(diǎn)相連接的條數(shù)叫做頂點(diǎn)的度。
4,圖可以分為有向圖和無向圖兩種,有向圖的邊有方向。
5,在有向圖中,度可以分為入度和出度(Out-degree)
6,帶權(quán)圖:在帶權(quán)圖中,每條邊都有一個(gè)權(quán)重
二:鄰接矩陣存儲(chǔ)方法
1,圖最直觀的一種存儲(chǔ)方法是:鄰接矩陣(Adjacency Matrix),鄰接矩陣的底層依賴一個(gè)二維數(shù)組。
2,用鄰接矩陣來表示一個(gè)圖,雖然簡單,直觀,但是浪費(fèi)存儲(chǔ)空間。
①:對于無向圖的二維數(shù)組中,如果將其對角線劃分為上下兩部分,那我們只需要利用上面或者下面這樣的一半的空間就足夠了,另一半白白浪費(fèi)掉了。
②:若存儲(chǔ)的是稀疏圖(Sparse Matrix),即頂點(diǎn)很多,但每個(gè)頂點(diǎn)的邊并不多,那鄰接矩陣的存儲(chǔ)方法就更加浪費(fèi)空間了。
3,用鄰接矩陣存儲(chǔ)的優(yōu)點(diǎn):
①:存儲(chǔ)方式簡單,直接,因?yàn)榛跀?shù)組,所以在獲取兩個(gè)頂點(diǎn)的關(guān)系時(shí),就非常高效。
②:其次是計(jì)算方便。因?yàn)?#xff0c;可以將很多圖的運(yùn)算轉(zhuǎn)換成矩陣之間的運(yùn)算。如求解最短路徑問題時(shí)會(huì)提到一個(gè)Floyd-Warshall算法,就是利用矩陣循環(huán)相乘若干次得到結(jié)果。
三:鄰接表存儲(chǔ)方法
1,鄰接表(Adjacency List)可以解決鄰接矩陣存儲(chǔ)方式比較浪費(fèi)內(nèi)存空間的問題
2,鄰接矩陣存儲(chǔ)起來比較浪費(fèi)空間,但使用比較節(jié)省時(shí)間,鄰接表存儲(chǔ)與之相反。
如圖中,如果要確定是否存在從頂點(diǎn)2到頂點(diǎn)4的邊,就需要遍歷頂點(diǎn)2對應(yīng)的鏈表,看那條鏈表中是否存在頂點(diǎn)4。但鏈表的存儲(chǔ)方式對緩存不友好。
3,我們可以將鄰接表中國的鏈表改成平衡二叉查找樹,實(shí)際開發(fā)中國還可選用紅黑樹。這樣可以快速查找兩個(gè)頂點(diǎn)之間是否存在邊了。
四:圖的應(yīng)用
如何存儲(chǔ)微博,微信、QQ等社交網(wǎng)絡(luò)中的好友關(guān)系?
數(shù)據(jù)結(jié)構(gòu)是為算法服務(wù)的,所以具體選擇哪種存儲(chǔ)方法,與期望支持的操作有關(guān)系。針對微博的用戶關(guān)系,需要支持:
? 判斷用戶A是否關(guān)注了用戶B;
? 判斷用戶A是否是用戶B的粉絲
? 用戶A關(guān)注用戶B;
? 用戶A取消關(guān)注用戶B;
? 根據(jù)用戶名稱的首字母排序,分頁獲取用戶的粉絲列表;
? 根據(jù)用戶名稱的首字母排序,分頁獲取用戶的關(guān)注列表。
3 。因?yàn)樯缃痪W(wǎng)絡(luò)是一張稀疏圖,使用鄰接矩陣存儲(chǔ)比較浪費(fèi)存儲(chǔ)空間,所以使用鄰接表來存儲(chǔ)。
4,但用一個(gè)鄰接表來存儲(chǔ)這種有向圖是不夠的,查找某個(gè)用戶關(guān)注了哪些用戶非常容易,但是如果想要知道某個(gè)用戶都被哪些用戶關(guān)注了,是非常困難的。因此,需要一個(gè)逆鄰接表。鄰接表中存儲(chǔ)了用戶的關(guān)注關(guān)系,逆鄰接表中存儲(chǔ)的是用戶的被關(guān)注關(guān)系。
對應(yīng)到圖上,鄰接表中,每個(gè)頂點(diǎn)的鏈表中,存儲(chǔ)的就是這個(gè)頂點(diǎn)指向的頂點(diǎn),逆鄰接表中,每個(gè)頂點(diǎn)的鏈表中,存儲(chǔ)的是指向這個(gè)頂點(diǎn)的頂點(diǎn)。
因?yàn)槲覀冃枰凑沼脩裘Q的首字母排序,分頁來獲取用戶的粉絲列表或者關(guān)注列表,用跳表這種結(jié)構(gòu)再合適不過了。這是因?yàn)?#xff0c;跳表插入、刪除、查找都非常高效,時(shí)間復(fù)雜度是 O(logn),空間復(fù)雜度上稍高,是 O(n)。最重要的一點(diǎn),跳表中存儲(chǔ)的數(shù)據(jù)本來就是有序的了,分頁獲取粉絲列表或關(guān)注列表,就非常高效。
1 內(nèi)存中用鄰接表;
2 要持久化存儲(chǔ)就用數(shù)據(jù)庫
2 超大圖 并且涉及大量圖計(jì)算。用專業(yè)的圖數(shù)據(jù)庫
筆記整理來源: 王爭 數(shù)據(jù)結(jié)構(gòu)與算法之美
總結(jié)
以上是生活随笔為你收集整理的【数据结构与算法】图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做自己喜欢的人
- 下一篇: 算法五——字符串匹配(上)