1. 程式人生 > 實用技巧 >圖(Graph)的學習

圖(Graph)的學習

文章目錄

圖的認識

圖(Graph)是由頂點和連線頂點的邊構成的離散結構。一個圖就是一些頂點的集合,這些頂點通過一系列邊結對(連線)。頂點用圓圈表示,邊就是這些圓圈之間的連線。頂點之間通過邊連線。

圖是最靈活的資料結構之一,很多問題都可以使用圖模型進行建模求解。
樹可以說只是圖的特例,但樹比圖複雜很多

在這裡插入圖片描述

注意:頂點有時也稱為節點或者交點,邊有時也稱為連結。

圖有各種形狀和大小。邊可以有權重(weight),即每一條邊會被分配一個正數或者負數值。邊可以是有方向的。有方向的邊意味著是單方面的關係。從頂點 X 到 頂點 Y 的邊是將 X 聯向 Y,不是將 Y 聯向 X。

樹和連結串列,都可以被當成是樹,是一種更簡單的形式。他們都有頂點(節點)和邊(連線)。
在這裡插入圖片描述

圖的概念

圖是由頂點集合以及頂點間的關係集合組成的一種資料結構。
由頂點 V 集和邊 E 集構成,因此圖可以表示成 Graph = (V,E)
V是頂點的有窮非空集合;E是頂點之間關係的有窮集合,也叫邊集合。

(1)有向圖:頂點對<x,y>是有序的;無向圖:頂點對<x,y>是無序的。
(2)無向邊:若頂點Vi到Vj之間的邊沒有方向,則稱這條邊為無向邊,用無序偶對(Vi,Vj)來表示

無向圖

如果圖中任意兩個頂點時間的邊都是無向邊,則稱該圖為無向圖:
  在這裡插入圖片描述
上圖是無向圖,所以連線頂點A與D的邊,可以表示為無序對(A,D),也可以寫成(D,A)

對於如上無向圖來說,G=(V,{E}) 其中頂點集合V={A,B,C,D};邊集合E={(A,B),(B,C),(C,D),(D,A),(A,C)}

有向圖

在這裡插入圖片描述

有向邊:若從頂點Vi到Vj的邊有方向,則稱這條邊為有向邊,也稱為弧。
用有序偶<Vi,Vj>來表示,Vi稱為弧尾,Vj稱為弧頭。

連線頂點A到D的有向邊就是弧,A是弧尾,D是弧頭,<A,D>表示弧。注意不能寫成<D,A>。
對於如上有向圖來說,G=(V,{E})其中頂點集合V={A,B,C,D};弧集合E={<A,D>,<B,A>,<C,A>,<B,C>}

(3)完全無向圖:若有n個頂點的無向圖有n(n-1)/2 條邊, 則此圖為完全無向圖。

(4)完全有向圖:有n個頂點的有向圖有n(n-1)條邊, 則此圖為完全有向圖。

(5)樹中根節點到任意節點的路徑是唯一的,但是圖中頂點與頂點之間的路徑卻不是唯一的。路徑的長度是路徑上的邊或弧的數目。
(6)如果對於圖中任意兩個頂點都是連通的,則成G是連通圖。 (7)圖按照邊或弧的多少分稀疏圖和稠密圖。
如果任意兩個頂點之間都存在邊叫完全圖,有向的叫有向圖。若無重複的邊或頂點到自身的邊則叫簡單圖。
(8)圖中頂點之間有鄰接點。無向圖頂點的邊數叫做度。有向圖頂點分為入度和出度。
(9)圖上的邊和弧上帶權則稱為網。
(10)有向的連通圖稱為強連通圖。

有向圖:具有方向性,頂點 (u,v)之間的關係和頂點 (v,u)之間的關係不同,後者或許不存在。
加權圖:與加權圖對應的就是無權圖,又叫等權圖。如果一張圖不含權重資訊,我們認為邊與邊之間沒有差別。

鄰接(adjacency):鄰接是兩個頂點之間的一種關係。如果圖包含 (u,v),則稱頂點v 與頂點u鄰接。在無向圖中,這也意味著頂點 u 與頂點 v 鄰接。

關聯(incidence):關聯是邊和頂點之間的關係。在有向圖中,邊 (u,v)從頂點 u開始關聯到 v,或者相反,從v關聯到u。在有向圖中,邊不一定是對稱的,有去無回是完全有可能的。
無向圖中,頂點的度就是與頂點相關聯的邊的數目,沒有入度和出度。
路徑(path):依次遍歷頂點序列之間的邊所形成的軌跡。
簡單路徑:沒有重複頂點的路徑稱為簡單路徑。

在這裡插入圖片描述

環:包含相同的頂點兩次或者兩次以上。上圖序列 < 1 , 2 , 4 , 3 , 1 > <1,2,4,3,1> <1,2,4,3,1>,1出現了兩次,當然還有其它的環,比如 < 1 , 4 , 3 , 1 > <1,4,3,1> <1,4,3,1>。

無環圖:沒有環的圖,其中,有向無環圖有特殊的名稱(DAG(Directed Acyline Graph)
下面這個概念很重要:
在這裡插入圖片描述
連通的:無向圖中每一對不同的頂點之間都有路徑。如果這個條件在有向圖裡也成立,那麼是強連通的。

有向圖的連通分支:將有向圖的方向忽略後,任何兩個頂點之間總是存在路徑,則該有向圖是弱連通的。有向圖的子圖是強連通的,且不包含在更大的連通子圖中,則可以稱為圖的強連通分支。
在這裡插入圖片描述
上圖, a 、e沒有到 { b , c , d } 中的頂點的路徑,所以各自是獨立的連通分支。因此,上圖有三個強連通分支,用集合寫出來就是: { { a } , { e } , { b , c , d } }

割點:如果移除某個頂點將使圖或者分支失去連通性,則稱該頂點為割點。某些特定的頂點對於保持圖或連通分支的連通性有特殊的重要意義。

雙連通圖:不含任何割點的圖。
割點的重要性不言而喻。如果你想要破壞網際網路,你就應該找到它的關節點。同樣,要防範敵人的攻擊,首要保護的也應該是關節點
橋(割邊):和割點類似,刪除一條邊,就產生比原圖更多的連通分支的子圖,這條邊就稱為割邊或者橋。

圖的表示

鄰接列表

鄰接列表:在鄰接列表實現中,每一個頂點會儲存一個從它這裡開始的邊的列表。比如,如果頂點A 有一條邊到B、C和D,那麼A的列表中會有3條邊
在這裡插入圖片描述
鄰接列表只描述了指向外部的邊。A 有一條邊到B,但是B沒有邊到A,所以 A沒有出現在B的鄰接列表中。

鄰接矩陣

圖最常見的表示形式為鄰接連結串列和鄰接矩陣

鄰接矩陣,顧名思義,是一個矩陣,一個儲存著邊的資訊的矩陣,而頂點則用矩陣的下標表示。對於一個鄰接矩陣M,如果M(i,j)=1,則說明頂點i和頂點j之間存在一條邊,對於無向圖來說,M (j ,i) = M (i, j),所以其鄰接矩陣是一個對稱矩陣;對於有向圖來說,則未必是一個對稱矩陣。鄰接矩陣的對角線元素都為0。下圖是一個無向圖和對應的鄰接矩陣:
在這裡插入圖片描述
在這裡插入圖片描述
需要注意的是,當邊上有權值的時候,稱之為網圖,則鄰接矩陣中的元素不再僅是0和1了,鄰接矩陣M中的元素定義為:
在這裡插入圖片描述

鄰接矩陣:在鄰接矩陣實現中,由行和列都表示頂點,由兩個頂點所決定的矩陣對應元素表示這裡兩個頂點是否相連、如果相連這個值表示的是相連邊的權重。例如,如果從頂點A到頂點B有一條權重為 5.6 的邊,那麼矩陣中第A行第B列的位置的元素值應該是5.6:

在這裡插入圖片描述
鄰接列表在表示稀疏圖時非常緊湊而成為了通常的選擇,但稀疏圖表示時使用鄰接矩陣,會浪費很多記憶體空間,遍歷的時候也會增加開銷。
如果圖是稠密圖,可以選擇更加方便的鄰接矩陣。
還有,頂點之間有多種關係的時候,也不適合使用矩陣。因為表示的時候,矩陣中的每一個元素都會被當作一個表

圖的遍歷

深度優先遍歷

深度優先遍歷(Depth_First_Search),也稱為深度優先搜尋,簡稱DFS。
在這裡插入圖片描述

廣度優先遍歷

廣度優先遍歷(Breadth_First_Search),又稱為廣度優先搜尋,簡稱BFS。
深度遍歷類似樹的前序遍歷,廣度優先遍歷類似於樹的層序遍歷。
在這裡插入圖片描述