大話數據結構5 - 圖

線性結構:一對一
樹形結構:一對多
圖形結構:多對多

圖:頂點的(有窮非空)集合、頂點之間邊的集合
G(V,E),G圖,V頂點,E邊
注意:
1、數據元素:線性->元素,樹->結點,圖->頂點vertex
2、空表,空樹,但是沒有空圖:頂點集不能爲空,邊集可以是空的

一:圖graph,簡單圖
1、無向邊,無序偶對(vi,vj)=(vj,vi)
無向圖:頂點n,邊e、0≦e≦n*(n-1)/2
無向完全圖:n,e=n*(n-1)/2
2、有向邊、弧,有序偶<vi,vj>、vi弧尾、vj弧頭,≠<vj,vi>
有向圖:頂點n,邊e、0≦e≦n*(n-1)
有向完全圖:n,e=n*(n-1)
3、稀疏圖,稠密圖
4、網network,權weight:頂點到頂點的距離或耗費
5、子圖

二:頂點與邊的關係,G=( V,{E} )
1、鄰接點,相關聯,度
無向圖:頂點v、v'互爲鄰接點,邊與頂點相關聯,頂點v的度TD(v),邊
有向圖:頂點v鄰接到頂點v'、頂點v'鄰接自頂點v,弧與頂點相關聯,頂點v的度TD(v)=ID(v)+OD(v)、入度InDegree、出度OutDegree,邊
2、路徑、頂點序列,路徑長度,簡單路徑
有向圖,路徑也是有向的
注意:樹中根到任意結點的路徑是唯一的,圖中頂點與頂點的路徑是不唯一的
3、迴路、環,簡單迴路、簡單環

三:連通圖
注意:有路徑就是連通,來回都有路徑就是(強)連通圖
1、無向圖:頂點v、v'有路徑、v與v'連通,連通圖,連通分量:極大連通子圖
連通圖的生成樹:極小連通子圖,頂點n、邊n-1
注意:有n個頂點、n-1條邊的不一定是生成樹
注意:一個圖有n個頂點,1.小於n-1條邊,則是非連通圖,2.多於n-1條邊,則是一個環
2、有向圖:頂點v到v',v'到v都有路徑,強連通圖,強連通分量:極大強連通子圖
有向樹,生成森林
注意:有向樹、生成森林都不是強連通圖

四:圖的抽象數據類型

五:圖的存儲結構,G=( V,{E} ),頂點n、邊e
不適合:簡單順序存儲、多重鏈表
1、鄰接矩陣,數組+數組,邊表/集是數組,重要
一維數組存儲頂點,二維數組(鄰接矩陣)存儲邊/弧
頂點數組vertex[n],邊/弧數組arc[n][n]、n*n的方陣
無向圖:邊數組是對稱矩陣、aij=aji,頂點vi的度=邊數組第i行元素之和
有向圖:弧數組不對稱,頂點的入度=列元素之和、出度=行元素之和
網:有邊/弧=wij(權值),對角線=0,無邊/弧=∞(極限值)
無向網圖,有向網圖
適用:稠密圖,讀存數據較多、結構修改較少的圖
缺點:如果是稀疏圖就會造成空間浪費
2、鄰接表,數組+單鏈表,邊表/集是鏈表,重要
一維數組存頂點,單鏈表存鄰接點(構成的線性表)的下標
頂點表,邊表、出邊表:以頂點爲弧尾來存儲
逆鄰接表,入邊表:以頂點爲弧頭的表
適用:稀疏圖,讀存數據較少、結構修改較多的圖
缺點:對於有向圖,有了出邊表就沒有入邊表,有了入邊表就沒有出邊表
 
3、十字鏈表,數組+多重鏈表,鄰接表+逆鄰接表,有向圖鄰接表的優化存儲結構
用於有向圖的應用

4、鄰接多重表,數組+多重鏈表,無向圖鄰接表的優化存儲結構
用於無向圖的應用
5、邊集數組,數組+數組,考慮的是對邊的關注
一維數組存儲頂點,一維數組存儲邊/弧
頂點數組[n],邊/弧數組[e]、e(begin,end,weight)
適合對邊依次進行處理的操作

六:圖的遍歷
同樹的遍歷類似:次序、訪問、所有頂點、有且僅有一次被訪問
訪問數組:有了訪問數組,就可以確定該頂點是否被訪問過,避免頂點重複被訪問,需要注意的是,當碰到重複的頂點時,該頂點已經被標記過了,就不會被訪問,而是再返回原路徑繼續查找沒有被訪問過的頂點。
注意:遍歷中強調,所有頂點有且僅有一次被訪問,指的是頂點信息只能被訪問一次,而不是指到達頂點的路徑只可以走一次,所以路徑是可以重複
1、深度優先遍歷:DFS,depth first search,深度優先搜索,遞歸,類似樹的前序遍歷
2、廣度優先遍歷:BFS,breadth first search,廣度優先搜索,類似樹的層序遍歷
對於非連通圖,對它的連通分量進行遍歷
注意:1和2僅僅在於對頂點的訪問順序不同,選擇哪種遍歷算法,要看遍歷的目的

七:圖的應用及算法
注意:1和2都是有環圖的應用,無向、有向都可以;3和4是有向無環圖(即圖中沒有迴路)的應用,也是工程問題上的應用
注意:樹結構中,根結點到任意結點的路徑唯一,生成樹也是樹結構
注意:環結構中,從一個頂點到另一個頂點的路徑不唯一,即有兩條及以上的路徑可以選

1、最小生成樹,無向有環圖:連通網的最小代價生成樹
注意:這裏僅討論了無向圖的最小生成樹;有向圖的最小生成樹,稱爲最小樹形圖,這裏併爲講解/涉及
網結構,頂點n,邊n-1,連通圖,生成樹,極小連通子圖
注意:生成樹要求包括所有頂點n個和保留n-1條邊
①普里姆(Prim)算法:以某頂點爲起點,逐步找各頂點上最小權值的邊來構建最小生成樹,走一步看一步,使用鄰接矩陣結構
算法:一維數組adjvex[頂點數]、lowcost[頂點數]
注意:此算法適用稠密圖,即邊非常多的情況
②克魯斯卡爾(Kruskal)算法:以邊爲目的去構建最小生成樹(注意要考慮是否會形成環路),即從最短邊開始,逐步在剩下的邊中選擇一條不會產生環路的具有最小權值的邊來構建最小生成樹,從全局入手,使用邊集數組結構
算法:一維數組parent[頂點數]
注意:此算法適用稀疏圖,即邊數少的情況

2、最短路徑,有環圖,路徑選擇
注意:無向圖、有向圖都可以求最短路徑
源點,終點
非網圖:邊數最少
網圖:權值之和最少
①迪傑斯特拉(Dijkstra)算法:按路徑長度遞增的次序產生最短路徑的算法,換句話說是,基於已經求出的最短路徑的基礎上,求得更遠頂點的最短路徑,使用鄰接矩陣結構
算法:一維數組P[頂點數]:路徑、D[頂點數]:最小權值和
注意:此算法是,從某個源點到其餘各頂點的最短路徑問題
注意:在最外添加一層循環,可以變成所有頂點到所有頂點的最短路徑問題
②弗洛伊德(Floyd)算法:使用鄰接矩陣結構,n是頂點數
二維數組D[n][n]:最短路徑權值和矩陣,初始化:網圖的鄰接矩陣
二維數組P[n][n]:前驅矩陣、存儲路徑,初始化:P[i][j]=j
D0[v][w]=min{D-1[v][w],D-1[v][0]+D-1[0][w]}
Dk[v][w]=min{Dk-1[v][w],Dk-1[v][k]+Dk-1[k][w]},中轉頂點k(0kn-1)
注意:此算法是,所有頂點到所有頂點的最短路徑問題

3、拓撲排序,有向無環圖,主要是解決一個工程是否能順利進行的問題
㈠概念:
a.項目工程、活動、子工程:所有的活動組成一個工程,其中若干個活動組成一個子工程
b.AOV網:actiivity on vertex network,一個表示工程的有向圖中,頂點表示活動,弧表示優先關係,這種有向圖的頂點表示活動的網,稱爲AOV網,AOV網是表示工程流程,用來對工程建模的
AOV網的工程特性:只有在進入某頂點的各項活動都已經結束,該頂點表示的活動纔可以開始
注意:AOV網不能存在迴路,即這樣的工程圖是無環的有向圖
c.拓撲序列:有向圖的頂點序列,滿足從vi到vj有一條路徑,在頂點序列中vi在vj前面
注意:拓撲序列不唯一
拓撲排序:對一個有向圖構造拓撲序列的過程
注意:構造時,如果所有頂點都在序列中,說明該有向圖不存在環/迴路,是AOV網;如果哪怕少了一個頂點,說明該有向圖有環/迴路,不是AOV網
㈡算法:研究AOV網的拓撲排序更有價值,可以用在工程、項目流程圖
使用鄰接表結構,增加入度域in、棧結構stack、以空間換時間
注意:malloc函數、sizeof函數,入棧stack[++top]=i,出棧gettop=stack[top--]

4、關鍵路徑,有向無環圖,主要是解決工程完成需要的最短時間問題
㈠概念:
a.AOE網:actiivity on edge network,一個表示工程的帶權有向圖中,頂點表示事件,弧表示活動,弧上的權值表示活動的持續時間,這種有向圖的弧表示活動的網,稱爲AOE網,AOE網也是表示工程流程的,用來對工程建模的
AOE網的工程特性:在某頂點表示的事件發生後,從該頂點出發的各項活動才能開始,只有在進入某頂點的各項活動都已經結束,該頂點表示的事件才能發生
始點/源點,終點/匯點
注意:一般情況下,AOE網只有一個源點一個匯點,但也可以有多個,那就是複雜流程圖了
AOV網和AOE網的不同:AOV網是頂點表示活動的網,只描述活動之間的制約關係問題;AOE網是弧表示活動、弧權值表示活動持續時間的網,是建立在活動之間制約關係沒有矛盾的基礎之上,再來分析完成整個工程至少需要的時間,或者爲縮短完成工程所需時間,應當加快哪些活動等問題
b.關鍵路徑:一條路徑的權值和,稱爲路徑長度;從源點到匯點路徑長度最大的路徑,稱爲關鍵路徑;關鍵路徑上的活動,稱爲關鍵活動
注意:反過來,關鍵活動組成的路徑就是關鍵路徑
注意:關鍵路徑可以有唯一條,也可以有多條,如果有多條關鍵路徑,那麼必須同時縮短這幾條關鍵路徑的路徑長度,即提高路徑上的活動的速度,纔可以達到縮短工期的目的
注意:多條關鍵路徑上的關鍵活動可能是存在重複,也可能不存在重複
㈡算法:
原理:活動的最早開始時間=最晚開始時間,該活動就是關鍵活動
使用鄰接表結構,棧結構stack2,n是頂點數,k(0kn-1)
事件最早和最晚發生時間etv、ltv(一維數組),活動最早和最晚開始時間ete、lte(變量)
事件最早發生時間,事件k的etv

P[K]表示所有到達頂點Vk的弧的集合,len<vi,vk>表示弧<vi,vk>的權值。
事件最晚發生時間,事件k的ltv

P[K]表示所有從頂點Vk出發的弧的集合,len<vk,vj>表示弧<vk,vj>的權值。
活動最早開始時間,活動<vi,vj>ete:ete=etv[i]
活動最晚開始時間,活動<vi,vj>lte:lte=ltv[j]-len<vi,vj>
算法步驟:
①從源點到匯點求拓撲排序,一邊將排序的頂點序號壓入棧stack2,一邊求etv
②初始化ltv[i]=etv[n-1],n是頂點數
③拓撲排序反過來進行,即從匯點到源點,逆序輸出拓撲排序的頂點序號,一邊將棧stack2中的序號出棧(逆序),一邊求ltv
④遍歷每個頂點及其弧表,求ete、lte、關鍵活動,並輸出弧
⑤最後打印出的路徑,就是關鍵路徑
注意:最後求的不是表示事件的頂點,而是最短時間,是弧組成的路徑,即關鍵活動組成的關鍵路徑
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章