數(shù)據(jù)結(jié)構(gòu)(嚴(yán)蔚敏)課件第7章_第1頁(yè)
數(shù)據(jù)結(jié)構(gòu)(嚴(yán)蔚敏)課件第7章_第2頁(yè)
數(shù)據(jù)結(jié)構(gòu)(嚴(yán)蔚敏)課件第7章_第3頁(yè)
數(shù)據(jù)結(jié)構(gòu)(嚴(yán)蔚敏)課件第7章_第4頁(yè)
數(shù)據(jù)結(jié)構(gòu)(嚴(yán)蔚敏)課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩108頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第七章圖9/28/20231頁(yè)【課前思考】1.同學(xué)們有沒(méi)有發(fā)現(xiàn)現(xiàn)在的十字路口的交通燈已從過(guò)去的一對(duì)改為三對(duì),即每個(gè)方向的直行、左拐和右拐能否通行都有相應(yīng)的交通燈指明。你能否對(duì)某個(gè)丁字路口的6條通路畫(huà)出和第一章緒論中介紹的"五叉路口交通管理示意圖"相類(lèi)似的圖?同學(xué)們一定可以畫(huà)出如下所示類(lèi)似的圖形。

2.如果每次讓三條路同時(shí)通行,那么從圖看出哪些路可以同時(shí)通行?同時(shí)可通行的路為:(AB,BC,CA),(AB,BC,BA),(AB,AC,CA),(CB,CA,BC)9/28/20232【學(xué)習(xí)目標(biāo)】1.領(lǐng)會(huì)圖的類(lèi)型定義。

2.熟悉圖的各種存儲(chǔ)結(jié)構(gòu)及其構(gòu)造算法,了解各種存儲(chǔ)結(jié)構(gòu)的特點(diǎn)及其選用原則。

3.熟練掌握?qǐng)D的兩種遍歷算法。

4.理解各種圖的應(yīng)用問(wèn)題的算法。9/28/20233【重點(diǎn)和難點(diǎn)】圖的應(yīng)用極為廣泛,而且圖的各種應(yīng)用問(wèn)題的算法都比較經(jīng)典,因此本章重點(diǎn)在于理解各種圖的算法及其應(yīng)用場(chǎng)合?!局R(shí)點(diǎn)】圖的類(lèi)型定義、圖的存儲(chǔ)表示、圖的深度優(yōu)先搜索遍歷和圖的廣度優(yōu)先搜索遍歷、無(wú)向網(wǎng)的最小生成樹(shù)、最短路徑、拓?fù)渑判?、關(guān)鍵路徑。9/28/20234【學(xué)習(xí)指南】

離散數(shù)學(xué)中的圖論是專(zhuān)門(mén)研究圖性質(zhì)的一個(gè)數(shù)學(xué)分支,但圖論注重研究圖的純數(shù)學(xué)性質(zhì),而數(shù)據(jù)結(jié)構(gòu)中對(duì)圖的討論則側(cè)重于在計(jì)算機(jī)中如何表示圖以及如何實(shí)現(xiàn)圖的操作和應(yīng)用等。圖是較線性表和樹(shù)更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu),因此和線性表、樹(shù)不同,雖然在遍歷圖的同時(shí)可以對(duì)頂點(diǎn)或弧進(jìn)行各種操作,但更多圖的應(yīng)用問(wèn)題如求最小生成樹(shù)和最短路徑等在圖論的研究中都早已有了特定算法,在本章中主要是介紹它們?cè)谟?jì)算機(jī)中的具體實(shí)現(xiàn)。這些算法乍一看都比較難,應(yīng)多對(duì)照具體圖例的存儲(chǔ)結(jié)構(gòu)進(jìn)行學(xué)習(xí)。而圖遍歷的兩種搜索路徑和樹(shù)遍歷的兩種搜索路徑極為相似,應(yīng)將兩者的算法對(duì)照學(xué)習(xí)以便提高學(xué)習(xí)的效果。本章必須完成的算法設(shè)計(jì)題為

:7.7,7.9,7.10,7.12,7.14,7.15,7.229/28/202357.1圖的定義與術(shù)語(yǔ)7.2圖的存儲(chǔ)表示7.3圖的遍歷7.4最小生成樹(shù)7.5重(雙)連通圖和關(guān)節(jié)點(diǎn)7.6兩點(diǎn)之間的最短路徑問(wèn)題7.7拓?fù)渑判?.8關(guān)鍵路徑9/28/20236

圖是由一個(gè)頂點(diǎn)集V和一個(gè)弧集R構(gòu)成的數(shù)據(jù)結(jié)構(gòu)。Graph=(V,VR)其中,VR={<v,w>|v,w∈V且P(v,w)}

<v,w>表示從v到w的一條弧,并稱(chēng)v為弧頭,w為弧尾。

謂詞P(v,w)定義了弧<v,w>的意義或信息。圖的結(jié)構(gòu)定義:7.1圖的定義與術(shù)語(yǔ)9/28/20237

由于“弧”是有方向的,因此稱(chēng)由頂點(diǎn)集和弧集構(gòu)成的圖為有向圖。

ABECD例如:G1=(V1,VR1)其中V1={A,B,C,D,E}VR1={<A,B>,<A,E>,<B,C>,<C,D>,<D,B>,<D,A>,<E,C>}9/28/20238若<v,w>VR必有<w,v>VR,則稱(chēng)(v,w)為頂點(diǎn)v和頂點(diǎn)w之間存在一條邊。

BCADFE由頂點(diǎn)集和邊集構(gòu)成的圖稱(chēng)作無(wú)向圖。例如:G2=(V2,VR2)V2={A,B,C,D,E,F}VR2={(A,B),(A,E),(B,E),(C,D),(D,F),(B,F),(C,F)}9/28/20239名詞和術(shù)語(yǔ)網(wǎng)、子圖

完全圖、稀疏圖、稠密圖鄰接點(diǎn)、度、入度、出度路徑、路徑長(zhǎng)度、簡(jiǎn)單路徑、簡(jiǎn)單回路連通圖、連通分量、強(qiáng)連通圖、強(qiáng)連通分量生成樹(shù)、生成森林9/28/202310ABECFAEFBBC設(shè)圖G=(V,{VR})和圖G=(V,{VR}),且VV,VRVR,則稱(chēng)G為G的子圖。1597211132

弧或邊帶權(quán)的圖分別稱(chēng)作有向網(wǎng)或無(wú)向網(wǎng)。C9/28/202311假設(shè)圖中有

n

個(gè)頂點(diǎn),e

條邊,則

含有e=n(n-1)/2條邊的無(wú)向圖稱(chēng)作完全圖;

含有e=n(n-1)條弧的有向圖稱(chēng)作

有向完全圖;若邊或弧的個(gè)數(shù)e<nlogn,則稱(chēng)作稀疏圖,否則稱(chēng)作稠密圖。9/28/202312

假若頂點(diǎn)v和頂點(diǎn)w之間存在一條邊,則稱(chēng)頂點(diǎn)v和w互為鄰接點(diǎn),ACDFE例如:ID(B)=3ID(A)=2邊(v,w)

和頂點(diǎn)v和w相關(guān)聯(lián)。

和頂點(diǎn)v關(guān)聯(lián)的邊的數(shù)目定義為頂點(diǎn)v的度。B9/28/202313頂點(diǎn)的出度:以頂點(diǎn)v為弧尾的弧的數(shù)目;ABECF對(duì)有向圖來(lái)說(shuō),頂點(diǎn)的入度:以頂點(diǎn)v為弧頭的弧的數(shù)目。頂點(diǎn)的度(TD)=出度(OD)+入度(ID)例如:ID(B)=2OD(B)=1TD(B)=39/28/202314設(shè)圖G=(V,{VR})中的一個(gè)頂點(diǎn)序列{u=vi,0,vi,1,…,vi,m=w}中,(vi,j-1,vi,j)VR1≤j≤m,則稱(chēng)從頂點(diǎn)u到頂點(diǎn)w之間存在一條路徑。路徑上邊(或弧)的數(shù)目稱(chēng)作路徑長(zhǎng)度。ABECF如:長(zhǎng)度為3的路徑{A,B,C,F}簡(jiǎn)單路徑:序列中頂點(diǎn)不重復(fù)出現(xiàn)的路徑。簡(jiǎn)單回路:序列中第一個(gè)頂點(diǎn)和最后一個(gè)頂點(diǎn)相同的路徑而其余頂點(diǎn)不重復(fù)。9/28/202315若圖G中任意兩個(gè)頂點(diǎn)之間都有路徑相通,則稱(chēng)此圖為連通圖;若無(wú)向圖為非連通圖,則圖中各個(gè)極大連通子圖稱(chēng)作此圖的連通分量。BACDFEBACDFE9/28/202316

若任意兩個(gè)頂點(diǎn)之間都存在一條有向路徑,則稱(chēng)此有向圖為強(qiáng)連通圖。ABECFABECF對(duì)有向圖,否則,其各個(gè)強(qiáng)連通子圖稱(chēng)作它的強(qiáng)連通分量。9/28/202317

假設(shè)一個(gè)連通圖有n個(gè)頂點(diǎn)和e條邊,其中n-1條邊和n個(gè)頂點(diǎn)構(gòu)成一個(gè)極小連通子圖,稱(chēng)該極小連通子圖為此連通圖的生成樹(shù)。對(duì)非連通圖,則稱(chēng)由各個(gè)連通分量的生成樹(shù)的集合為此非連通圖的生成森林。BACDFE9/28/202318結(jié)構(gòu)的建立和銷(xiāo)毀插入或刪除頂點(diǎn)對(duì)鄰接點(diǎn)的操作對(duì)頂點(diǎn)的訪問(wèn)操作遍歷插入和刪除弧基本操作9/28/202319CreatGraph(&G,V,VR)://按定義(V,VR)構(gòu)造圖DestroyGraph(&G)://銷(xiāo)毀圖結(jié)構(gòu)的建立和銷(xiāo)毀9/28/202320對(duì)頂點(diǎn)的訪問(wèn)操作LocateVex(G,u);

//若G中存在頂點(diǎn)u,則返回該頂點(diǎn)在//圖中“位置”

;否則返回其它信息。GetVex(G,v);//返回v的值。PutVex(&G,v,value);//對(duì)v賦值value。9/28/202321對(duì)鄰接點(diǎn)的操作FirstAdjVex(G,v);

//返回v的“第一個(gè)鄰接點(diǎn)”。若該頂點(diǎn)//在G中沒(méi)有鄰接點(diǎn),則返回“空”。NextAdjVex(G,v,w);

//返回v的(相對(duì)于w的)“下一個(gè)鄰接//點(diǎn)”。若w是v的最后一個(gè)鄰接點(diǎn),則//返回“空”。9/28/202322插入或刪除頂點(diǎn)InsertVex(&G,v);

//在圖G中增添新頂點(diǎn)v。DeleteVex(&G,v);//刪除G中頂點(diǎn)v及其相關(guān)的弧。9/28/202323插入和刪除弧InsertArc(&G,v,w);//在G中增添弧<v,w>,若G是無(wú)向的,//則還增添對(duì)稱(chēng)弧<w,v>。DeleteArc(&G,v,w);

//在G中刪除弧<v,w>,若G是無(wú)向的,//則還刪除對(duì)稱(chēng)弧<w,v>。9/28/202324遍歷DFSTraverse(G,v,Visit());//從頂點(diǎn)v起深度優(yōu)先遍歷圖G,并對(duì)每//個(gè)頂點(diǎn)調(diào)用函數(shù)Visit一次且僅一次。BFSTraverse(G,v,Visit());

//從頂點(diǎn)v起廣度優(yōu)先遍歷圖G,并對(duì)每//個(gè)頂點(diǎn)調(diào)用函數(shù)Visit一次且僅一次。9/28/2023257.2圖的存儲(chǔ)表示一、圖的數(shù)組(鄰接矩陣)存儲(chǔ)表示二、圖的鄰接表存儲(chǔ)表示三、有向圖的十字鏈表存儲(chǔ)表示四、無(wú)向圖的鄰接多重表存儲(chǔ)表示9/28/202326Aij={0(i,j)VR1(i,j)VR一、圖的數(shù)組(鄰接矩陣)存儲(chǔ)表示BACDFE定義:矩陣的元素為9/28/202327有向圖的鄰接矩陣為非對(duì)稱(chēng)矩陣ABECF9/28/202328typedefstructArcCell{//弧的定義VRTypeadj;//VRType是頂點(diǎn)關(guān)系類(lèi)型。//對(duì)無(wú)權(quán)圖,用1或0表示相鄰否;//對(duì)帶權(quán)圖,則為權(quán)值類(lèi)型。InfoType*info;//該弧相關(guān)信息的指針}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];9/28/202329typedefstruct{//圖的定義VertexType//頂點(diǎn)信息vexs[MAX_VERTEX_NUM];AdjMatrixarcs;//弧的信息

intvexnum,arcnum;//頂點(diǎn)數(shù),弧數(shù)GraphKindkind;//圖的種類(lèi)標(biāo)志

}MGraph;9/28/2023300A141B0452C353D254E015F123BACDFE二、圖的鄰接表存儲(chǔ)表示9/28/202331142301201234ABCDE有向圖的鄰接表

ABECD可見(jiàn),在有向圖的鄰接表中不易找到指向該頂點(diǎn)的弧。9/28/202332ABECD有向圖的逆鄰接表ABCDE303420

01234在有向圖的鄰接表中,對(duì)每個(gè)頂點(diǎn),鏈接的是指向該頂點(diǎn)的弧。9/28/202333typedefstructArcNode{

intadjvex;//該弧所指向的頂點(diǎn)的位置

structArcNode*nextarc;//指向下一條弧的指針I(yè)nfoType*info;//該弧相關(guān)信息的指針}ArcNode;adjvexnextarcinfo弧的結(jié)點(diǎn)結(jié)構(gòu)9/28/202334typedefstructVNode{

VertexTypedata;//頂點(diǎn)信息ArcNode*firstarc;//指向第一條依附該頂點(diǎn)的弧

}VNode,AdjList[MAX_VERTEX_NUM];datafirstarc頂點(diǎn)的結(jié)點(diǎn)結(jié)構(gòu)9/28/202335typedefstruct{

AdjListvertices;

intvexnum,arcnum;

intkind;//圖的種類(lèi)標(biāo)志}ALGraph;圖的結(jié)構(gòu)定義9/28/202336三、有向圖的十字鏈表存儲(chǔ)表示

弧的結(jié)點(diǎn)結(jié)構(gòu)弧尾頂點(diǎn)位置弧頭頂點(diǎn)位置弧的相關(guān)信息指向下一個(gè)有相同弧尾的結(jié)點(diǎn)指向下一個(gè)有相同弧頭的結(jié)點(diǎn)typedefstructArcBox{//弧的結(jié)構(gòu)表示

inttailvex,headvex;InfoType*info;structArcBox*hlink,*tlink;

}VexNode;9/28/202337頂點(diǎn)的結(jié)點(diǎn)結(jié)構(gòu)頂點(diǎn)信息數(shù)據(jù)指向該頂點(diǎn)的第一條入弧指向該頂點(diǎn)的第一條出弧typedefstructVexNode{//頂點(diǎn)的結(jié)構(gòu)表示VertexTypedata;ArcBox*firstin,*firstout;}VexNode;9/28/202338typedefstruct{VexNodexlist[MAX_VERTEX_NUM];//頂點(diǎn)結(jié)點(diǎn)(表頭向量)

intvexnum,arcnum;//有向圖的當(dāng)前頂點(diǎn)數(shù)和弧數(shù)}OLGraph;有向圖的結(jié)構(gòu)表示(十字鏈表)9/28/202339四、無(wú)向圖的鄰接多重表存儲(chǔ)表示typedefstructEbox{VisitIfmark;//訪問(wèn)標(biāo)記

intivex,jvex;//該邊依附的兩個(gè)頂點(diǎn)的位置

structEBox*ilink,*jlink;//分別指向依附這兩個(gè)頂點(diǎn)的下一條邊InfoType*info;//該邊信息指針}EBox;邊的結(jié)構(gòu)表示9/28/202340typedefstruct{//鄰接多重表

VexBoxadjmulist[MAX_VERTEX_NUM];

intvexnum,edgenum;

}AMLGraph;頂點(diǎn)的結(jié)構(gòu)表示typedefstructVexBox{VertexTypedata;EBox*firstedge;//指向第一條依附該頂點(diǎn)的邊}VexBox;無(wú)向圖的結(jié)構(gòu)表示9/28/2023417.3圖的遍歷

從圖中某個(gè)頂點(diǎn)出發(fā)游歷圖,訪遍圖中其余頂點(diǎn),并且使圖中的每個(gè)頂點(diǎn)僅被訪問(wèn)一次的過(guò)程。深度優(yōu)先搜索廣度優(yōu)先搜索遍歷應(yīng)用舉例9/28/202342

從圖中某個(gè)頂點(diǎn)V0出發(fā),訪問(wèn)此頂點(diǎn),然后依次從V0的各個(gè)未被訪問(wèn)的鄰接點(diǎn)出發(fā)深度優(yōu)先搜索遍歷圖,直至圖中所有和V0有路徑相通的頂點(diǎn)都被訪問(wèn)到。一、深度優(yōu)先搜索遍歷圖連通圖的深度優(yōu)先搜索遍歷9/28/202343Vw1SG1SG2SG3W1、W2和W3

均為V的鄰接點(diǎn),SG1、SG2和SG3分別為含頂點(diǎn)W1、W2和W3

的子圖。訪問(wèn)頂點(diǎn)V:for(W1、W2、W3)

若該鄰接點(diǎn)W未被訪問(wèn),

則從它出發(fā)進(jìn)行深度優(yōu)先搜索遍歷。w2w3w29/28/202344從上頁(yè)的圖解可見(jiàn):1.從深度優(yōu)先搜索遍歷連通圖的過(guò)程類(lèi)似于樹(shù)的先根遍歷;解決的辦法是:為每個(gè)頂點(diǎn)設(shè)立一個(gè)“訪問(wèn)標(biāo)志visited[w]”。2.如何判別V的鄰接點(diǎn)是否被訪問(wèn)?9/28/202345voidDFS(GraphG,intv){//從頂點(diǎn)v出發(fā),深度優(yōu)先搜索遍歷連通圖Gvisited[v]=TRUE;VisitFunc(v);

for(w=FirstAdjVex(G,v);w!=0;w=NextAdjVex(G,v,w))

if(!visited[w])DFS(G,w);

//對(duì)v的尚未訪問(wèn)的鄰接頂點(diǎn)w//遞歸調(diào)用DFS}//DFS9/28/202346首先將圖中每個(gè)頂點(diǎn)的訪問(wèn)標(biāo)志設(shè)為FALSE,之后搜索圖中每個(gè)頂點(diǎn),如果未被訪問(wèn),則以該頂點(diǎn)為起始點(diǎn),進(jìn)行深度優(yōu)先搜索遍歷,否則繼續(xù)檢查下一頂點(diǎn)。非連通圖的深度優(yōu)先搜索遍歷9/28/202347voidDFSTraverse(GraphG,

Status(*Visit)(intv)){

//對(duì)圖G作深度優(yōu)先遍歷。VisitFunc=Visit;

for(v=0;v<G.vexnum;++v)visited[v]=FALSE;//訪問(wèn)標(biāo)志數(shù)組初始化

for(v=0;v<G.vexnum;++v)

if(!visited[v])DFS(G,v);//對(duì)尚未訪問(wèn)的頂點(diǎn)調(diào)用DFS}9/28/202348abchdekfgFFFFFFFFFTTTTTTTTTachdkfebgachkfedbg訪問(wèn)標(biāo)志:訪問(wèn)次序:例如:0123456789/28/202349二、廣度優(yōu)先搜索遍歷圖Vw1w8w3w7w6w2w5w4對(duì)連通圖,從起始點(diǎn)V到其余各頂點(diǎn)必定存在路徑。其中,V->w1,V->w2,V->w8

的路徑長(zhǎng)度為1;V->w7,V->w3,V->w5

的路徑長(zhǎng)度為2;V->w6,V->w4

的路徑長(zhǎng)度為3。w1Vw2w7w6w3w8w5w49/28/202350從圖中的某個(gè)頂點(diǎn)V0出發(fā),并在訪問(wèn)此頂點(diǎn)之后依次訪問(wèn)V0的所有未被訪問(wèn)過(guò)的鄰接點(diǎn),之后按這些頂點(diǎn)被訪問(wèn)的先后次序依次訪問(wèn)它們的鄰接點(diǎn),直至圖中所有和V0有路徑相通的頂點(diǎn)都被訪問(wèn)到。若此時(shí)圖中尚有頂點(diǎn)未被訪問(wèn),則另選圖中一個(gè)未曾被訪問(wèn)的頂點(diǎn)作起始點(diǎn),重復(fù)上述過(guò)程,直至圖中所有頂點(diǎn)都被訪問(wèn)到為止。9/28/202351

voidBFSTraverse(GraphG,

Status(*Visit)(intv)){

for(v=0;v<G.vexnum;++v)visited[v]=FALSE;//初始化訪問(wèn)標(biāo)志

InitQueue(Q);

//置空的輔助隊(duì)列Q

for(v=0;v<G.vexnum;++v)

if(

!visited[v]){

//v尚未訪問(wèn)

}

}//BFSTraverse……9/28/202352visited[v]=TRUE;Visit(v);//訪問(wèn)uEnQueue(Q,v);

//v入隊(duì)列while(!QueueEmpty(Q)){

DeQueue(Q,u);//隊(duì)頭元素出隊(duì)并置為ufor(w=FirstAdjVex(G,u);w!=0;w=NextAdjVex(G,u,w))

if(!visited[w])

{

visited[w]=TRUE;Visit(w);EnQueue(Q,w);

//訪問(wèn)的頂點(diǎn)w入隊(duì)列}//if}//while9/28/202353三、遍歷應(yīng)用舉例1.求一條從頂點(diǎn)i到頂點(diǎn)s的簡(jiǎn)單路徑2.

求兩個(gè)頂點(diǎn)之間的一條路徑長(zhǎng)度最短的路徑9/28/2023541.

求一條從頂點(diǎn)i到頂點(diǎn)s的簡(jiǎn)單路徑abchdekfg求從頂點(diǎn)b到頂點(diǎn)k的一條簡(jiǎn)單路徑。從頂點(diǎn)b出發(fā)進(jìn)行深度優(yōu)先搜索遍歷。例如:假設(shè)找到的第一個(gè)鄰接點(diǎn)是a,則得到的結(jié)點(diǎn)訪問(wèn)序列為:b

adhce

kfg。假設(shè)找到的第一個(gè)鄰接點(diǎn)是c,則得到的結(jié)點(diǎn)訪問(wèn)序列為:

b

chdae

kfg,9/28/2023551.從頂點(diǎn)i到頂點(diǎn)s,若存在路徑,則從頂點(diǎn)i出發(fā)進(jìn)行深度優(yōu)先搜索,必能搜索到頂點(diǎn)s。2.

遍歷過(guò)程中搜索到的頂點(diǎn)不一定是路徑上的頂點(diǎn)。結(jié)論:3.

由它出發(fā)進(jìn)行的深度優(yōu)先遍歷已經(jīng)完成的頂點(diǎn)不是路徑上的頂點(diǎn)。9/28/202356voidDFSearch(intv,ints,char*PATH){//從第v個(gè)頂點(diǎn)出發(fā)遞歸地深度優(yōu)先遍歷圖G,//求得一條從v到s的簡(jiǎn)單路徑,并記錄在PATH中visited[v]=TRUE;//訪問(wèn)第v個(gè)頂點(diǎn)

Append(PATH,getVertex(v));

//第v個(gè)頂點(diǎn)加入路徑

for(w=FirstAdjVex(v);w!=0&&!found;

w=NextAdjVex(v))

if(w=s){found=TRUE;Append(PATH,w);}

else

if(!visited[w])DFSearch(w,s,PATH);if(!found)Delete(PATH);

//從路徑上刪除頂點(diǎn)v

}9/28/2023572.

求兩個(gè)頂點(diǎn)之間的一條路徑長(zhǎng)度最短的路徑

若兩個(gè)頂點(diǎn)之間存在多條路徑,則其中必有一條路徑長(zhǎng)度最短的路徑。如何求得這條路徑?9/28/202358abchdekfg因此,求路徑長(zhǎng)度最短的路徑可以基于廣度優(yōu)先搜索遍歷進(jìn)行,但需要修改鏈隊(duì)列的結(jié)點(diǎn)結(jié)構(gòu)及其入隊(duì)列和出隊(duì)列的算法。深度優(yōu)先搜索訪問(wèn)頂點(diǎn)的次序取決于圖的存儲(chǔ)結(jié)構(gòu),而廣度優(yōu)先搜索訪問(wèn)頂點(diǎn)的次序是按“路徑長(zhǎng)度”漸增的次序。9/28/202359例如:求下圖中頂點(diǎn)3至頂點(diǎn)5的一條最短路徑。鏈隊(duì)列的狀態(tài)如下所示:

312475

Q.front

Q.rear3214756899/28/2023601)將鏈隊(duì)列的結(jié)點(diǎn)改為“雙鏈”結(jié)點(diǎn)。即結(jié)點(diǎn)中包含next和prior兩個(gè)指針;2)修改入隊(duì)列的操作。插入新的隊(duì)尾結(jié)點(diǎn)時(shí),令其prior域的指針指向剛剛出隊(duì)列的結(jié)點(diǎn),即當(dāng)前的隊(duì)頭指針?biāo)附Y(jié)點(diǎn);3)修改出隊(duì)列的操作。出隊(duì)列時(shí),僅移動(dòng)隊(duì)頭指針,而不將隊(duì)頭結(jié)點(diǎn)從鏈表中刪除。9/28/202361typedef

DuLinkListQueuePtr;

voidInitQueue(LinkQueue&Q){

Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));

Q.front->next=Q.rear->next=NULL}voidEnQueue(LinkQueue&Q,QelemTypee){p=(QueuePtr)malloc(sizeof(QNode));p->data=e;p->next=NULL;

p->prior=Q.front

Q.rear->next=p;Q.rear=p;}voidDeQueue(LinkQueue&Q,QelemType&e){

Q.front=Q.front->next;e=Q.front->data}9/28/2023627.4(連通網(wǎng)的)最小生成樹(shù)

假設(shè)要在n個(gè)城市之間建立通訊聯(lián)絡(luò)網(wǎng),則連通n個(gè)城市只需要修建n-1條線路,如何在最節(jié)省經(jīng)費(fèi)的前提下建立這個(gè)通訊網(wǎng)?問(wèn)題:9/28/202363構(gòu)造網(wǎng)的一棵最小生成樹(shù),即:在e條帶權(quán)的邊中選取n-1條邊(不構(gòu)成回路),使“權(quán)值之和”為最小。算法二:(克魯斯卡爾算法)該問(wèn)題等價(jià)于:算法一:(普里姆算法)9/28/202364

取圖中任意一個(gè)頂點(diǎn)v作為生成樹(shù)的根,之后往生成樹(shù)上添加新的頂點(diǎn)w。在待添加的頂點(diǎn)w和已經(jīng)在生成樹(shù)上的頂點(diǎn)v之間必定存在一條邊,并且該邊的權(quán)值在所有連通頂點(diǎn)v和w之間的邊中取值最小。之后繼續(xù)往生成樹(shù)上添加頂點(diǎn),直至生成樹(shù)上含有n個(gè)頂點(diǎn)為止。普里姆算法的基本思想:9/28/202365abcdegf例如:195141827168213ae12dcbgf7148531621所得生成樹(shù)權(quán)值和=14+8+3+5+16+21=679/28/202366在生成樹(shù)的構(gòu)造過(guò)程中,圖中n個(gè)頂點(diǎn)分屬兩個(gè)集合:已落在生成樹(shù)上的頂點(diǎn)集U

和尚未落在生成樹(shù)上的頂點(diǎn)集V-U,則應(yīng)在所有連通U中頂點(diǎn)和V-U中頂點(diǎn)的邊中選取權(quán)值最小的邊。

一般情況下所添加的頂點(diǎn)應(yīng)滿(mǎn)足下列條件:9/28/202367設(shè)置一個(gè)輔助數(shù)組,對(duì)當(dāng)前V-U集中的每個(gè)頂點(diǎn),記錄和頂點(diǎn)集U中頂點(diǎn)相連接的代價(jià)最小的邊:struct{VertexTypeadjvex;//U集中的頂點(diǎn)序號(hào)VRTypelowcost;//邊的權(quán)值}closedge[MAX_VERTEX_NUM];9/28/202368abcdegf195141827168213ae12dcb7aaa19141814例如:e12ee8168d3dd7213c559/28/202369voidMiniSpanTree_P(MGraphG,VertexTypeu){//用普里姆算法從頂點(diǎn)u出發(fā)構(gòu)造網(wǎng)G的最小生成樹(shù)

k=LocateVex(G,u);

for(j=0;j<G.vexnum;++j)//輔助數(shù)組初始化

if(j!=k)

closedge[j]={u,G.arcs[k][j].adj};

closedge[k].lowcost=0;//初始,U={u}

for(i=0;i<G.vexnum;++i){}繼續(xù)向生成樹(shù)上添加頂點(diǎn);9/28/202370

k=minimum(closedge);

//求出加入生成樹(shù)的下一個(gè)頂點(diǎn)(k)

printf(closedge[k].adjvex,G.vexs[k]);//輸出生成樹(shù)上一條邊closedge[k].lowcost=0;//第k頂點(diǎn)并入U(xiǎn)集for(j=0;j<G.vexnum;++j)//修改其它頂點(diǎn)的最小邊

if(G.arcs[k][j].adj<closedge[j].lowcost)closedge[j]={G.vexs[k],G.arcs[k][j].adj};

9/28/202371具體做法:先構(gòu)造一個(gè)只含n個(gè)頂點(diǎn)的子圖SG,然后從權(quán)值最小的邊開(kāi)始,若它的添加不使SG中產(chǎn)生回路,則在SG上加上這條邊,如此重復(fù),直至加上n-1條邊為止??紤]問(wèn)題的出發(fā)點(diǎn):為使生成樹(shù)上邊的權(quán)值之和達(dá)到最小,則應(yīng)使生成樹(shù)中每一條邊的權(quán)值盡可能地小??唆斔箍査惴ǖ幕舅枷耄?/28/202372abcdegf195141827168213ae12dcbgf7148531621例如:71218199/28/202373算法描述:構(gòu)造非連通圖ST=(V,{});k=i=0;//k計(jì)選中的邊數(shù)while(k<n-1){++i;檢查邊集E中第i條權(quán)值最小的邊(u,v);

若(u,v)加入ST后不使ST中產(chǎn)生回路,

則輸出邊(u,v);

且k++;}9/28/202374普里姆算法克魯斯卡爾算法時(shí)間復(fù)雜度O(n2)O(eloge)稠密圖稀疏圖算法名適應(yīng)范圍比較兩種算法9/28/2023757.5重(雙)連通圖和關(guān)節(jié)點(diǎn)

若從一個(gè)連通圖中刪去任何一個(gè)頂點(diǎn)及其相關(guān)聯(lián)的邊,它仍為一個(gè)連通圖的話,則該連通圖被稱(chēng)為重(雙)連通圖。問(wèn)題:9/28/202376

若連通圖中的某個(gè)頂點(diǎn)和其相關(guān)聯(lián)的邊被刪去之后,該連通圖被分割成兩個(gè)或兩個(gè)以上的連通分量,則稱(chēng)此頂點(diǎn)為關(guān)節(jié)點(diǎn)。沒(méi)有關(guān)節(jié)點(diǎn)的連通圖為雙連通圖。如何判別給定的連通圖是否是雙連通圖?9/28/202377ahgcbfdeabcdefgh1234567833111111例如:下列連通圖中,頂點(diǎn)

a

和頂點(diǎn)c

是關(guān)節(jié)點(diǎn)深度優(yōu)先生成樹(shù)9/28/202378關(guān)節(jié)點(diǎn)有何特征?

假設(shè)從某個(gè)頂點(diǎn)V0出發(fā)對(duì)連通圖進(jìn)行深度優(yōu)先搜索遍歷,則可得到一棵深度優(yōu)先生成樹(shù),樹(shù)上包含圖的所有頂點(diǎn)。需借助圖的深度優(yōu)先生成樹(shù)來(lái)分析。9/28/202379

若生成樹(shù)的根結(jié)點(diǎn),有兩個(gè)或兩個(gè)以上的分支,則此頂點(diǎn)(生成樹(shù)的根)必為關(guān)節(jié)點(diǎn);

對(duì)生成樹(shù)上的任意一個(gè)“頂點(diǎn)”,若其某棵子樹(shù)的根或子樹(shù)中的其它“頂點(diǎn)”沒(méi)有和其祖先相通的回邊,則該“頂點(diǎn)”必為關(guān)節(jié)點(diǎn)。9/28/202380對(duì)上述兩個(gè)判定準(zhǔn)則在算法中如何實(shí)現(xiàn)?9/28/2023811)設(shè)V0為深度優(yōu)先遍歷的出發(fā)點(diǎn)

p=G.vertices[0].firstarc;v=p->adjvex;

DFSArticul(G,v);

//從第v頂點(diǎn)出發(fā)深度優(yōu)先搜索

if

(count<G.vexnum)

{

//生成樹(shù)的根有至少兩棵子樹(shù)

printf(0,G.vertices[0].data);

//根是關(guān)節(jié)點(diǎn)9/28/2023822)定義函數(shù):low(v)=Min{visited[v],low[w],visited[k]}

其中:頂點(diǎn)w

是生成樹(shù)上頂點(diǎn)v

的孩子;頂點(diǎn)k

是生成樹(shù)上和頂點(diǎn)v由回邊相聯(lián)接的祖先;visited記錄深度優(yōu)先遍歷時(shí)的訪問(wèn)次序

若對(duì)頂點(diǎn)v,在生成樹(shù)上存在一個(gè)子樹(shù)根w,

low[w]≥visited[v]

則頂點(diǎn)v為關(guān)節(jié)點(diǎn)。9/28/202383對(duì)深度優(yōu)先遍歷算法作如下修改:1.visited[v]的值改為遍歷過(guò)程中頂點(diǎn)的訪問(wèn)次序count值;

2.遍歷過(guò)程中求得

low[v]=Min{visited[v],low[w],visited[k]}3.從子樹(shù)遍歷返回時(shí),判別low[w]≥visited[v]?9/28/202384for(p=G.vertices[v0].firstarc;p;

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論