數據結構-圖(Graph)



返回 我的研究方向(Research Interests)



圖的定義


圖(Graph)是由頂點的有窮非空集合和頂點之間邊的集合組成,通常表示為:G(V,E),其中,G表示一個圖,V是圖G中頂點的集合,E是圖G中邊的集合。

網絡中的點通常稱為節點(Node);圖中的點則常稱為頂點(Vertex)
線性表中數據元素叫做元素;樹中將數據元素叫做結點;在圖中數據元素叫做頂點(Vertex)

無向邊

若頂點\(V_i\)\(V_j\)之間的邊沒有方向,則稱這條邊為無向邊(Edge),用無序偶對(\(V_i\)\(V_j\))表示。簡化寫成\(e_{ij}\)

無向圖

如果圖中任意兩個頂點之間的邊都是無向邊,則稱該圖為無向圖(Undirected graphs)。
無向圖

Code Implementation(Python)
# 需要導入networkx、matplotlib庫
import networkx as nx
import matplotlib.pyplot as plt
# 創建對象
G = nx.Graph()
V = ["V1", "V2", "V3", "V4", "V5"]  # 一個元組
# 添加地頂點
G.add_nodes_from(V)
# 通過添加list來添加多條邊
G.add_edges_from([("V1", "V2"), ("V1", "V3"), ("V1", "V5"), ("V2", "V5"), ("V2", "V4"), ("V2", "V3"),
                  ("V3", "V4")])  
# circular_layout:表示節點在一個圓環上均勻分布
pos = nx.circular_layout(G)  
nx.draw(G,
        pos=pos,
        with_labels=True,  # 節點是否帶標簽,默認True
        node_size=800,  # 節點大小,默認300
        node_color='#66CCFF',  # 節點顏色,默認red
        font_color='white',  # 節點標簽的字的顏色,默認黑色
        node_shape='o',  # 節點形狀,默認’o’
        alpha=1,  # 透明度,默認1,不透明
        edge_color='#CCFFFF',  # 邊的顏色,默認黑色
        width=3,  # 邊的寬度,默認1
        style='solid',  # 邊的樣式,默認為實線,可選擇solid、dashed、dotted、dashdot
        font_size=15  # 字體大小,默認12
        )
# 添加邊的屬性說明
edge_labels = {  
    ("V1", "V2"): "e12",
    ("V1", "V3"): "e13",
    ("V1", "V5"): "e15",
    ("V2", "V5"): "e25",
    ("V2", "V4"): "e24",
    ("V2", "V3"): "e23",
    ("V3", "V4"): "e34"
}
nx.draw_networkx_edge_labels(G,
                             pos,
                             edge_labels=edge_labels,
                             font_color="black"  # 屬性說明的字體顏色
                             )
plt.show()

上圖就是一個無向圖。

  • 由於是無向的,則有 \(e_{ij}\)=\(e_{ji}\)
    即頂點\(V_1\)到頂點\(V_2\)的邊,既可以寫成\(e_{12}\),也可以寫成 \(e_{21}\)
  • 上圖可以表示為G(V,E)
    其中頂點集合V={\(V_1,V_2,V_3,V_4,V_5\)},邊集合E={\((V_1,V_2),(V_1,V_3),(V_1,V_5),(V_2,V_5),(V_2,V_4),(V_2,V_3),(V_3,V_4)\)}

有向邊

若頂點\(V_i\)\(V_j\)之間的邊有方向,則稱這條邊為有向邊(Edge),也稱為弧(Arc),用有序偶對<\(V_i\)\(V_j\)>表示,\(V_i\)稱為弧尾(Tail),\(V_j\)稱為弧頭(Head)

有向圖

如果圖中任意兩個頂點之間的邊都是有向邊,則稱該圖為無向圖(Directed graphs)。
有向圖

Code Implementation(Python)
# 需要導入networkx、matplotlib庫
import networkx as nx
import matplotlib.pyplot as plt
# 創建對象
G = nx.DiGraph()
V = ["V1", "V2", "V3", "V4", "V5"]  # 一個元組
# 添加地頂點
G.add_nodes_from(V)
# 通過添加list來添加多條邊
G.add_edges_from([("V1", "V2"), ("V1", "V3"), ("V1", "V5"), ("V2", "V5"), ("V2", "V4"), ("V2", "V3"),
                  ("V3", "V4")])
# circular_layout:表示節點在一個圓環上均勻分布
pos = nx.circular_layout(G)
nx.draw(G,
        pos=pos,
        with_labels=True,  # 節點是否帶標簽,默認True
        node_size=800,  # 節點大小,默認300
        node_color='#66CCFF',  # 節點顏色,默認red
        font_color='white',  # 節點標簽的字的顏色,默認黑色
        node_shape='o',  # 節點形狀,默認’o’
        alpha=1,  # 透明度,默認1,不透明
        edge_color='#CCFFFF',  # 邊的顏色,默認黑色
        width=3,  # 邊的寬度,默認1
        style='solid',  # 邊的樣式,默認為實線,可選擇solid、dashed、dotted、dashdot
        font_size=15,  # 字體大小,默認12
        arrowstyle="->",  # 指定箭頭樣式
        arrowsize=20  # 指定箭頭大小
        )
# 添加邊的屬性說明
edge_labels = {
    ("V1", "V2"): "e12",
    ("V1", "V3"): "e13",
    ("V1", "V5"): "e15",
    ("V2", "V5"): "e25",
    ("V2", "V4"): "e24",
    ("V2", "V3"): "e23",
    ("V3", "V4"): "e34"
}
nx.draw_networkx_edge_labels(G,
                             pos,
                             edge_labels=edge_labels,
                             font_color="black"  # 屬性說明的字體顏色
                             )
plt.show()

上圖就是一個有向圖。

  • 由於是有向的,則有 \(e_{ij}\)\(e_{ji}\)
    即頂點\(V_1\)到頂點\(V_2\)的邊是有向邊,即弧,\(V_1\)是弧尾,\(V_2\)是弧頭,<\(V_1\)\(V_2\)>表示弧,注意不能寫成<\(V_2\)\(V_1\)>
  • 上圖可以表示為G(V,E)
    其中頂點集合V={\(V_1,V_2,V_3,V_4,V_5\)},邊集合E={\(<V_1,V_2>,<V_1,V_3>,<V_1,V_5>,<V_2,V_5>,<V_2,V_4>,<V_2,V_3>,<V_3,V_4>\)}

無向完全圖

在無向圖中,如果任意兩個頂點之間都存在邊,則稱該圖為無向完全圖。

含有n個頂點的無向完全圖有\(\frac{n×(n-1)}{2}\)條邊

下圖就是無向完全圖,因為每個頂點都要與除它以外的頂點連線,頂點A與BCD三個頂點連線,共有四個頂點,自然是4×3,但由於頂點A與頂點B連線后,計算B與A連線就是重復,因此要整體除以2,共有6條邊。

image-20210409091911940

有向完全圖

在有向圖中,如果任意兩個頂點之間都存在方向互為相反的兩條弧,則稱該圖為有向完全圖。

含有n個頂點的有向完全圖有\(n× (n-1)\)條邊

image-20210409092019652

對於具有n個頂點和e條邊數的圖,無向圖0≤e≤\(\frac{n×(n-1)}{2}\),有向圖0≤e≤\(n (n-1)\)

稀疏圖、稠密圖、權、網

有很少條邊或弧的圖稱為稀疏圖,反之稱為稠密圖。這里稀疏和稠密是模糊的概念,都是相對而言的。

有些圖的邊或弧具有與它相關的數字,這種與圖的邊或弧相關的數叫做權(Weight)。這些權可以表示從一個頂點到另一個頂點的距離或耗費。

這種帶權的圖通常稱為網(Network)。下圖就是一張帶權的圖,即標識中國四大城市的直線距離的網,此圖中的權就是兩地的距離。

image-20210409092245616

子圖

假設有兩個圖G= (V,E) 和 G'= (\(V^',E^‘),如果V^'被包含於V且E^'被包含於E,則稱G^'為G的\)子圖(Subgraph)

如下圖帶底紋的圖均為左側無向圖與有向圖的子圖。

image-20210409092840882

對於上圖中的無向圖。頂點V的度(Degree)是和V相關聯的邊的數目,記為TD (v)。

  • 頂點A與B互為鄰接點,邊(A,B)依附於頂點A與B上,頂點A的度為3。而此圖的邊數是5,各個頂點度的和=3+2+3+2=10,推敲后發現,邊數其實就是各頂點度數和的一半,多出的一半是因為重復兩次記數。簡記之:

    \[e = \frac{1}{2}\sum_{i=1}^{n} TD(V_i) \]

對於上圖中的有向圖。以頂點V為頭的弧的數目稱為V的入度(InDegree),記為ID(v);以V為尾的弧的數目稱為V的出度(OutDegree),記為OD(v);頂點V的度為 TD(v)=ID (v)+OD (v)。

  • 頂點A的入度是2(從B到A的弧,從C到A的弧),出度是1(從A到D的弧),所以頂點A的度為2+1=3。此有向圖的弧有4條,而各頂點的出度和=1+2+1+0=4,各頂點的入度和=2+0+1+1=4。所以得到:

    \[e = \sum_{i=1}^{n} ID(V_i)= \sum_{i=1}^{n} OD(V_i) \]

路徑長度

路徑的長度是路徑上的邊或弧的數目。

image-20210409094357125

回路或環、簡單路徑、簡單回路或簡單環

第一個頂點到最后一個頂點相同的路徑稱為回路或環(Cyce)。序列中頂點不重復出現的路徑稱為簡單路徑

除了第一個頂點和最后一個頂點之外,其余頂點不重復出現的回路,稱為簡單回路或簡單環

下圖兩個圖的粗線都構成環,左側的環因第一個頂點和最后一個頂點都是B,且C、D、A 沒有重復出現,因此是一個簡單環。而右側的環,由於頂點C的重復,它就不是簡單環了。

image-20210409094706089


連通圖相關術語


連通圖

在無向圖G中,如果從頂點V到頂點\(V^’\)有路徑,則稱V和\(V^’\)是連通的。

如果對於圖中任意兩個頂點\(V_i\)\(V_j\)∈E, \(V_i\)\(V_j\)都是連通的,則稱G是連通圖(ConnectedGraph)

下圖的圖1,它的頂點A到頂點B、C、D 都是連通的,但顯然頂點A與頂點E或F就無路徑,因此不能算是連通圖。圖2,頂點A、B、C、D相互都是連通的,所以它本身是連通圖。

image-20210409095059999

連通分量

無向圖中的極大連通子圖稱為連通分量。注意連通分量的概念,它強調:

  • 要是子圖;
  • 子圖要是連通的;
  • 連通子圖含有極大頂點數;
  • 具有極大頂點數的連通子圖包含依附於這些頂點的所有邊。

下圖的圖1是一個無向非連通圖。但是它有兩個連通分量,即圖2和圖3。而圖4,盡管是圖1的子圖,但是它卻不滿足連通子圖的極大頂點數(圖2滿足)。因此它不是圖1的無向圖的連通分量。

image-20210409095520478

強連通圖、強連通分量

在有向圖G中,如果對於每一對\(V_i、V_j ∈ V、V_i≠V_j ,從V_i到V_j 和從V_j 到V_i 都\)存在路徑,則稱G是強連通圖

有向圖中的極大強連通子圖稱做有向圖的強連通分量

例如下圖,圖1並不是強連通圖,因為頂點A到頂點D存在路徑,而D到A就不存在。圖2就是強連通圖,而且顯然圖2是圖1的極大強連通子圖,即是它的強連通分量。

image-20210409100318247

生成樹

一個連通圖的生成樹是一個極小的連通子圖,它含有圖中全部的n個頂點,但只有足以構成一棵樹的n-1條邊。

比如下圖的圖1是一普通圖,但顯然它不是生成樹,當去掉兩條構成環的邊后,比如圖2或圖3,就滿足n個頂點n-1條邊且連通的定義了。它們都是一棵生成樹。

從這里也可知道,如果一個圖有n個頂點和小於n-1條邊,則是非連通圖,如果它多於n-1邊條,必定構成一個環,因為這條邊使得它依附的那兩個頂點之間有了第二條路徑。比如圖2和圖3,隨便加哪兩頂點的邊都將構成環。不過有n-1條邊並不一定是生成樹,比如圖4。

image-20210409100810722

有向樹、生成森林

如果一個有向圖恰有一個頂點的入度為0,其余頂點的入度均為1,則是一棵有向樹。

對有向樹的理解比較容易,所謂入度為О其實就相當於樹中的根結點,其余頂點入度為1就是說樹的非根結點的雙親只有一個。一個有向圖的生成森林由若干棵有向樹組成,含有圖中全部頂點,但只有足以構成若干棵不相交的有向樹的弧。

如下圖的圖1是一棵有向圖。去掉一些弧后,它可以分解為兩棵有向樹,如圖2和圖3,這兩棵就是圖1有向圖的生成森林。

image-20210409101004155


總結


  • 按照有無方向分為無向圖和有向圖。無向圖由頂點構成,有向圖由頂點構成。弧有弧尾和弧頭之分。
  • 圖按照邊或弧的多少分稀疏圖稠密圖。如果任意兩個頂點之間都存在邊叫完全圖,有向的叫有向完全圖。若無重復的邊或頂點到自身的邊則叫簡單圖。
  • 圖中頂點之間有鄰接點、依附的概念。無向圖頂點的邊數叫做,有向圖頂點分為入度和出度
  • 圖上的邊或弧上帶則稱為
  • 圖中頂點間存在路徑,兩頂點存在路徑則說明是連通的,如果路徑最終回到起始點則稱為,當中不重復叫簡單路徑。若任意兩頂點都是連通的,則圖就
  • 連通圖,有向則稱強連通圖。圖中有子圖,若子圖極大連通則就是連通分量,有向的則稱強連通分量
  • 無向圖中連通且n個頂點n-1條邊叫生成樹。有向圖中一頂點入度為0其余頂點入度為1的叫有向樹。一個有向圖由若干棵有向樹構成生成森林

參考資料:
[1]程傑.大話數據結構[M].清華大學出版社:北京,2011.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM