資料結構:七 圖
1. 圖的定義
定義
-
圖(Graph)是由頂點的有窮非空集合和頂點之間邊的集合組成,通常表示為:G(V,E)
-
G 表示一個圖,V 是圖 G 中頂點的集合,E 是圖 G 中邊的集合
-
線性表中我們把資料元素叫元素,樹中將資料元素叫結點,在圖中資料元素,我們則稱之為頂點(Vertex)
-
在圖結構中,不允許沒有頂點。在定義中,若 V 是頂點的集合,則強調了頂點集合 V 有窮非空
- 線性表中可以沒有資料元素,稱為空表
- 樹中可以沒有結點,叫做空樹
-
圖中,任意兩個頂點之間都可能有關係,頂點之間的邏輯關係用邊來表示,邊集可以是空的
- 線性表中,相鄰的資料元素之間具有線性關係
- 樹結構中,相鄰兩層的結點具有層次關係
各種圖定義
-
無向邊:若頂點 vi 到 vj 之間的邊沒有方向,則稱這條邊為無向邊(Edge),用無序偶對(vi,vj)來表示
-
有向邊:若從頂點 vi 到 vj 的邊有方向,則稱這條邊為有向邊,也稱為弧(Arc)
- 用有序偶 <vi,vj> 來表示,vi 稱為弧尾(Tail),vj 稱為弧頭(Head)
-
簡單圖:在圖中,若不存在頂點到其自身的邊,且同一條邊不重複出現
-
無向完全圖:在無向圖中,如果任意兩個頂點之間都存在邊
-
有向完全圖:在有向圖中,如果任意兩個頂點之間都存在方向互為相反的兩條弧
-
有很少條邊或弧的圖稱為稀疏圖,反之稱為稠密圖
-
權(Weight):與圖的邊或弧相關的數
- 這些權可以表示從一個頂點到另一個頂點的距離或耗費
- 這種帶權的圖通常稱為網(Network)
圖的頂點與邊間關係
- 對於無向圖 G=(V,{E}),如果邊(v,v')屬於 E,則稱頂點 v 和 v' 互為鄰接點(Adjacent),即 v 和 v' 相鄰接
- 邊(v,v')依附(incident)於頂點 v 和 v',或者說(v,v')與頂點 v 和 v' 相關聯
- 頂點 v 的度(Degree)是和 v 相關聯的邊的數目,記作 TD(v)
- 路徑的長度是路徑上的邊或弧的數目
- 第一個頂點到最後一個頂點相同的路徑稱為迴路或環(Cycle)
- 序列中頂點不重複出現的路徑稱為簡單路徑
- 除了第一個頂點和最後一個頂點之外,其餘頂點不重複出現的迴路,稱為簡單迴路或簡單環
連通圖相關術語
-
在無向圖 G 中,如果從頂點 v 到頂點 v' 有路徑,則稱 v 和 v' 是連通的。
-
如果對於圖中任意兩個頂點 vi vj 屬於 E ,vi 和 vj 都是連通的,則稱 G 是連通圖(Connected Graph)
-
無向圖中的極大連通子圖稱為連通分量
- 要是子圖
- 子圖是連通的
- 連通子圖含有極大頂點數
- 具有極大頂點數的連通子圖包含依附於這些頂點的所有邊
-
在有向圖 G 中,如果對於每一對 vi vj 屬於 V,vi 不等於 vj,從 vi 到 vj 和從 vj 到 vi 都存在路徑,則稱 G 是強連通圖
-
有向圖中的極大強連通子圖稱做有向圖的強連通分量
-
連通圖的生成樹定義
- 一個連通圖的生成樹是一個極小的連通子圖,它含有圖中全部的 n 個頂點,但只有足以構成一棵樹的 n-1 條邊
- 如果一個有向圖恰有一個頂點的入度為 0,其餘頂點的入度為 1,則是一棵有向樹
- 一個有向樹的生成森林由若干棵有向樹組成,含有圖中全部頂點,但只有足以構成若干棵不相交的有向樹的弧
2. 圖的抽象資料型別
ADT 圖(Graph) Data 頂點的有窮非空集合和邊的集合 Operation CreateGraph(*G,V,VR):按照頂點集V和邊弧集VR的定義構造圖G DestroyGraph(*G):圖G存在則銷燬 LocateVex(G,u):若圖G中存在頂點u,則返回圖中位置 GetVex(G,v):返回圖中頂點v的值 PutVex(G,v,value):將圖G中頂點v賦值給value FirstAdjVex(G,*v):返回頂點v的一個鄰接頂點,若頂點在G中無鄰接頂點則返回空 NextAdjVex(G,v,*w):返回頂點v相對於頂點w的下一個鄰接頂點,若w是v的最後一個鄰接點則返回空 InsertVex(*G,v):在圖G中增加新頂點v DeleteVex(*G,v):刪除圖G中頂點v及其相關的弧 InsertArc(*G,v,w):在圖G中新增弧<v,w>,若G是無向圖,還需要新增對稱弧<w,v> DeleteArc(*G,v,w):在圖G中刪除弧<v,w>,若G是無向圖,則需要刪除對稱弧<w,v> DFSTraverse(G):對圖G中進行深度優先遍歷,在遍歷過程對每個頂點呼叫 HFSTraverse(G):對圖G中進行廣度優先遍歷,在遍歷過程對每個頂點呼叫
endADT
3. 圖的儲存結構
鄰接矩陣
-
圖的鄰接矩陣(Adjacency Matrix)儲存方式是用兩個陣列來表示圖
- 一個一維陣列儲存圖中頂點資訊
- 一個二位陣列(稱為鄰接矩陣)儲存圖中的邊或弧的資訊
-
對稱矩陣:n 階矩陣的元滿足 aij = aji(0 <= i, j <= n)
鄰接表
-
陣列與連結串列相結合的儲存方法稱為鄰接表(Adjacency List)
- 圖中頂點用一個一維陣列儲存,當然,頂點也可以用單鏈表來儲存,不過陣列可以較容易地讀取頂點資訊,更加方便
- 另外,對於頂點陣列中,每個資料元素還需要儲存指向第一個鄰接點的指標,以便於查詢該頂點的邊資訊
- 圖中每個頂點 vi 的所有鄰接點構成一個線性表,由於鄰接點的個數不定,所以用單鏈表儲存,無向圖稱為頂點 vi 的邊表,有向圖則稱為頂點 vi 作為弧尾的出邊表
-
無向圖的鄰接表結構
-
頂點表的各個結點由 data 和 firstedge 兩個域表示
- data 是資料域,儲存頂點的資訊,
- firstedge 是指標域,指向邊表的第一個結點,即此頂點的第一個鄰接點
-
邊表結點由 adjvex 和 next 兩個域組成
- adjvex 是鄰接點域,儲存某頂點的鄰接點在頂點表中的下標
- next 則儲存指向邊表中下一個結點的指標
-
-
有向圖的逆鄰接表
- 對每個頂點 vi 都建立一個連結為 vi 為弧頭的表
- 對帶權值得網圖,可在邊表結點定義中再增加一個 weight 的資料域,儲存權值資訊即可
十字連結串列
-
重新定義頂點表結點結構
- firstin 表示入邊表頭指標,指向該頂點的入邊表中第一個結點
- firstout 表示出邊表頭指標,指向該頂點的出邊表中的第一個結點
-
重新定義邊表結點結構
- tailvex 是指弧起點在頂點表的下標
- headvex 是指弧終點在頂點表中的下標
- headlink 是指入邊表指標域,指向終點相同的下一條邊
- taillink 是指邊表指標域,指向起點相同的下一條邊
- 如果是網,還可以增加一個 weight 域來儲存權值
鄰接多重表
-
重新定義邊表結點結構
- ivex 和 jvex 是與某條邊依附的兩個頂點在頂點表中下標
- ilink 指向依附頂點 ivex 的下一條邊
- jlink 指向依附頂點 jvex 的下一條邊
邊集陣列
-
邊集陣列是由兩個一維陣列構成
- 一個是儲存頂點的資訊
- 另一個是儲存邊的資訊,這個邊陣列每個資料元素由一條邊的起點下標(begin),終點下標(end)和權(weight)組成
-
定義的邊陣列結構
- begin 是儲存起點下標,end 是儲存終點下標,weight 是儲存權值
4. 圖的遍歷
從圖中某一頂點出發訪遍圖中其餘頂點,且使每一個頂點僅被訪問一次,這過程叫圖的遍歷
深度優先遍歷(Depth First Search,DFS)
-
對於連通圖
- 從圖中某個頂點 v 出發,訪問此頂點,然後從 v 的未被訪問的鄰接點出發深度優先遍歷圖,直至圖中所有和 v 有路徑相通的頂點都被訪問到
-
對於非連通圖
- 只需要對它的連通分量分別進行深度優先遍歷,即在先前一個頂點進行一次深度優先遍歷後,若圖中尚有頂點未被訪問,則另選圖中一個未曾被訪問的頂點作起始點,重複上述過程,直至圖中所有頂點都被訪問到為止
-
圖的深度優先遍歷類似樹的前序遍歷
-
深度遍歷更適合目標明確,以找到目標為主要目的
廣度優先遍歷(Breadth First Search,BFS)
- 圖的廣度優先遍歷就類似於樹的層序遍歷
- 廣度優先更適合在不斷擴大遍歷範圍時找到相對最優解
5. 最小生成樹
定義
- 構建連通網的最小代價生成樹
普利姆(Prim)演算法
- 以某頂點為起點,逐步找各頂點上最小權值的邊來構建最小生成樹
克魯斯卡爾(Kruskal)演算法
6. 最短路徑
定義
-
非網圖
- 由於非網圖它沒有邊上的權值,所謂的最短路徑,其實就是指兩頂點之間經過的邊數最少的路徑
-
網圖
- 對於網圖來說,最短路徑是指兩頂點之間經過的邊上權值之和最少的路徑,並且我們稱路徑上的第一個頂點是源點,最後一個頂點是終點
迪傑斯特拉(Dijkstra)演算法
弗洛伊德(Floyd)演算法
7. 拓撲排序
拓撲排序介紹
-
AOV 網(Activity On Vertex Network)
- 在一個表示工程的有向圖中,用頂點表示活動,用弧表示活動之間的優先關係,這樣的有向圖為頂點表示活動的網,我們稱為 AOV 網
-
拓撲序列
- 設 G=(V, E) 是一個具有 n 個頂點的有向圖,V 中的頂點序列 v1,v2,······,vn,滿足若從頂點 vi 到 vj 有一條路徑,則在頂點序列中頂點 vi 必在頂點 vj 之前。則我們稱這樣的頂點序列為一個拓撲序列
-
拓撲排序
-
對一個有向圖構造拓撲序列的過程
-
構造時會有兩個結果
- 如果此網的全部頂點都被輸出,則說明它是不存在環(迴路)的 AOV 網
- 如果輸出頂點數少了,哪怕是少了一個,也說明這個網存在環(迴路),不是 AOV 網
-
拓撲排序演算法
-
基本思路
- 從 AOV 網中選擇一個入度為 0 的頂點輸出,然後刪除此頂點,並刪除以此頂點為尾的弧,繼續重複此步驟,直到輸出全部頂點或者 AOV 網中不存在入度 0 的頂點為止
8. 關鍵路徑
定義
-
AOE 網
- 在一個表示工程的帶權有向圖中,用頂點表示事件,用有向邊表示活動,用邊上的權值表示活動的持續時間,這種有向圖的邊表示活動的網,我們稱之為 AOE 網(Activity On Edge Network)
- 沒有入邊的頂點稱為始點或源點
- 沒有出邊的頂點稱為終點或匯點
- 由於一個工程,總有一個開始一個結束,所以正常情況下,AOE 網只有一個源點一個匯點
-
路徑長度:路徑上各個活動所持續的時間之和
-
關鍵路徑:從源點到匯點具有最大長度的路徑
-
關鍵活動:在關鍵路徑上的活動
關鍵路徑演算法原理
-
找到所有活動的最早開始時間和最晚開始時間,並且比較它們,如果相等就意味著此活動是關鍵活動,活動間的路徑為關鍵路徑;如果不等,則就不是
-
引數定義
-
事件的最早發生時間 etv(earliest time of vertex)
- 即頂點 vk 的最早發生時間
-
事件的最晚發生時間 ltv(latest time of vertex)
- 即頂點 vk 的最晚發生時間,也就是每個頂點對應的事件最晚需要開始的時間,超出此時間將會延誤整個工期
-
活動的最早開工時間 ete(earliest time of edge)
- 即弧 ak 的最早發生時間
-
活動的最晚開工時間 lte(latest time of edge)
- 即弧 ak 的最晚發生時間,也就是不推遲工期的最晚開工時間
-