版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
7.1抽象數(shù)據(jù)類型圖的定義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)鍵路徑7.1抽象數(shù)據(jù)類型圖的定義7.2圖的存儲(chǔ)表示7.3圖的1圖的基本概念圖定義圖是由頂點(diǎn)集合(vertex)及頂點(diǎn)間的關(guān)系集合組成的一種數(shù)據(jù)結(jié)構(gòu):
Graph=(V,E)
其中
V={x|x某個(gè)數(shù)據(jù)對(duì)象}
是頂點(diǎn)的有窮非空集合;
E={(x,y)|x,y
V}
或
E={<x,y>|x,y
V&&Path(x,y)}
是頂點(diǎn)之間關(guān)系的有窮集合,也叫做邊(edge)集合。Path(x,y)表示從x到y(tǒng)的一條單向通路,它是有方向的。圖的基本概念圖定義圖是由頂點(diǎn)集合(vertex)及頂點(diǎn)2
有向圖與無(wú)向圖在有向圖中,頂點(diǎn)對(duì)<x,y>是有序的。在無(wú)向圖中,頂點(diǎn)對(duì)(x,y)是無(wú)序的。完全圖若有
n個(gè)頂點(diǎn)的無(wú)向圖有n(n-1)/2條邊,則此圖為完全無(wú)向圖。有
n個(gè)頂點(diǎn)的有向圖有n(n-1)條邊,則此圖為完全有向圖。00001111222265433有向圖與無(wú)向圖在有向圖中,頂點(diǎn)對(duì)<x,y>3
鄰接頂點(diǎn)如果
(u,v)是E(G)中的一條邊,則稱u與v互為鄰接頂點(diǎn)。子圖設(shè)有兩個(gè)圖G=(V,E)和G'=(V',E')。若V'V且E'E,則稱圖G'是圖G的子圖。權(quán)某些圖的邊具有與它相關(guān)的數(shù),稱之為權(quán)。這種帶權(quán)圖叫做網(wǎng)絡(luò)。子圖01230130123023鄰接頂點(diǎn)如果(u,v)是E(G)中的一4頂點(diǎn)的度一個(gè)頂點(diǎn)v的度是與它相關(guān)聯(lián)的邊的條數(shù)。記作TD(v)。在有向圖中,頂點(diǎn)的度等于該頂點(diǎn)的入度與出度之和。頂點(diǎn)v的入度是以v為終點(diǎn)的有向邊的條數(shù),記作
ID(v);頂點(diǎn)v的出度是以v為始點(diǎn)的有向邊的條數(shù),記作
OD(v)。路徑在圖G=(V,E)中,若從頂點(diǎn)
vi
出發(fā),沿一些邊經(jīng)過(guò)一些頂點(diǎn)
vp1,
vp2,…,
vpm,到達(dá)頂點(diǎn)vj。則稱頂點(diǎn)序列
(vi
vp1vp2...vpm
vj)
為從頂點(diǎn)vi到頂點(diǎn)
vj的路徑。它經(jīng)過(guò)的邊(vi,vp1)、(vp1,vp2)、...、(vpm,vj)應(yīng)是屬于E的邊。頂點(diǎn)的度一個(gè)頂點(diǎn)v的度是與它相關(guān)聯(lián)的邊的條數(shù)。記作TD(5路徑長(zhǎng)度非帶權(quán)圖的路徑長(zhǎng)度是指此路徑上邊的條數(shù)。帶權(quán)圖的路徑長(zhǎng)度是指路徑上各邊的權(quán)之和。簡(jiǎn)單路徑若路徑上各頂點(diǎn)v1,v2,...,vm
均不互相重復(fù),則稱這樣的路徑為簡(jiǎn)單路徑?;芈啡袈窂缴系谝粋€(gè)頂點(diǎn)v1與最后一個(gè)頂點(diǎn)vm重合,則稱這樣的路徑為回路或環(huán)。012301230123路徑長(zhǎng)度非帶權(quán)圖的路徑長(zhǎng)度是指此路徑上邊的條數(shù)。帶權(quán)圖的6連通圖與連通分量在無(wú)向圖中,若從頂點(diǎn)v1到頂點(diǎn)v2有路徑,則稱頂點(diǎn)v1與v2是連通的。如果圖中任意一對(duì)頂點(diǎn)都是連通的,則稱此圖是連通圖。非連通圖的極大連通子圖叫做連通分量。強(qiáng)連通圖與強(qiáng)連通分量在有向圖中,若對(duì)于每一對(duì)頂點(diǎn)vi和vj,都存在一條從vi到vj和從vj到vi的路徑,則稱此圖是強(qiáng)連通圖。非強(qiáng)連通圖的極大強(qiáng)連通子圖叫做強(qiáng)連通分量。生成樹(shù)一個(gè)連通圖的生成樹(shù)是其極小連通子圖,在n個(gè)頂點(diǎn)的情形下,有
n-1條邊。連通圖與連通分量在無(wú)向圖中,若從頂點(diǎn)v1到頂點(diǎn)v2有7
圖是由一個(gè)頂點(diǎn)集V和一個(gè)弧集R構(gòu)成的數(shù)據(jù)結(jié)構(gòu)。Graph=(V,R)其中,VR={<v,w>|v,w∈V且P(v,w)}
<v,w>表示從v到w的一條弧,并稱v為弧頭,w為弧尾。
謂詞P(v,w)定義了弧<v,w>的意義或信息。圖的結(jié)構(gòu)定義:圖是由一個(gè)頂點(diǎn)集V和一個(gè)弧集R構(gòu)成的數(shù)據(jù)結(jié)構(gòu)。8
由于“弧”是有方向的,因此稱由頂點(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>}由于“弧”是有方向的,因此稱由頂點(diǎn)集和弧集構(gòu)成的圖為有向9若<v,w>VR必有<w,v>VR,則稱(v,w)為頂點(diǎn)v和頂點(diǎn)w之間存在一條邊。
BCADFE由頂點(diǎn)集和邊集構(gòu)成的圖稱作無(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>}若<v,w>VR必有<w,v>VR,10名詞和術(shù)語(yǔ)網(wǎng)、子圖
完全圖、稀疏圖、稠密圖鄰接點(diǎn)、度、入度、出度路徑、路徑長(zhǎng)度、簡(jiǎn)單路徑、簡(jiǎn)單回路連通圖、連通分量、強(qiáng)連通圖、強(qiáng)連通分量生成樹(shù)、生成森林名詞和術(shù)語(yǔ)網(wǎng)、子圖完全圖、稀疏圖、稠密圖鄰接點(diǎn)、11ABECFAEABBC設(shè)圖G=(V,{VR})和圖G=(V,{VR}),且VV,VRVR,則稱G為G的子圖。1597211132
弧或邊帶權(quán)的圖分別稱作有向網(wǎng)或無(wú)向網(wǎng)。ABECFAEABBC設(shè)圖G=(V,{VR})和圖G=12假設(shè)圖中有
n
個(gè)頂點(diǎn),e
條邊,則
含有e=n(n-1)/2條邊的無(wú)向圖稱作完全圖;
含有e=n(n-1)條弧的有向圖稱作
有向完全圖;若邊或弧的個(gè)數(shù)e<nlogn,則稱作稀疏圖,否則稱作稠密圖。假設(shè)圖中有n個(gè)頂點(diǎn),e條邊,則含有e=n(n-113
假若頂點(diǎn)v和頂點(diǎn)w之間存在一條邊,則稱頂點(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ù)目定義為邊的度。B假若頂點(diǎn)v和頂點(diǎn)w之間存在一條邊,ACDFE例如:I14頂點(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)=3頂點(diǎn)的出度:以頂點(diǎn)v為弧尾的弧的數(shù)目;ABECF對(duì)有向圖來(lái)15設(shè)圖G=(V,{VR})中的一個(gè)頂點(diǎn)序列{u=vi,0,vi,1,…,vi,m=w}中,(vi,j-1,vi,j)VR1≤j≤m,則稱從頂點(diǎn)u到頂點(diǎn)w之間存在一條路徑。路徑上邊的數(shù)目稱作路徑長(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)相同的路徑。設(shè)圖G=(V,{VR})中的一個(gè)頂點(diǎn)序列ABECF如:長(zhǎng)度為16若圖G中任意兩個(gè)頂點(diǎn)之間都有路徑相通,則稱此圖為連通圖;若無(wú)向圖為非連通圖,則圖中各個(gè)極大連通子圖稱作此圖的連通分量。BACDFEBACDFE若圖G中任意兩個(gè)頂點(diǎn)之間都有路徑相通,則稱此圖為連通圖;若無(wú)17
若任意兩個(gè)頂點(diǎn)之間都存在一條有向路徑,則稱此有向圖為強(qiáng)連通圖。ABECFABECF對(duì)有向圖,否則,其各個(gè)強(qiáng)連通子圖稱作它的強(qiáng)連通分量。若任意兩個(gè)頂18
假設(shè)一個(gè)連通圖有n個(gè)頂點(diǎn)和e條邊,其中n-1條邊和n個(gè)頂點(diǎn)構(gòu)成一個(gè)極小連通子圖,稱該極小連通子圖為此連通圖的生成樹(shù)。對(duì)非連通圖,則稱由各個(gè)連通分量的生成樹(shù)的集合為此非連通圖的生成森林。BACDFE假設(shè)一個(gè)連通圖有n個(gè)頂點(diǎn)和e條邊,其中n-119結(jié)構(gòu)的建立和銷(xiāo)毀插入或刪除頂點(diǎn)對(duì)鄰接點(diǎn)的操作對(duì)頂點(diǎn)的訪問(wèn)操作遍歷插入和刪除弧基本操作結(jié)構(gòu)的建立和銷(xiāo)毀插入或刪除頂點(diǎn)對(duì)鄰接點(diǎn)的操作對(duì)頂點(diǎn)的訪問(wèn)操作20CreatGraph(&G,V,VR)://按定義(V,VR)構(gòu)造圖DestroyGraph(&G)://銷(xiāo)毀圖結(jié)構(gòu)的建立和銷(xiāo)毀CreatGraph(&G,V,VR):DestroyG21對(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。對(duì)頂點(diǎn)的訪問(wèn)操作LocateVex(G,u);GetV22對(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),則//返回“空”。對(duì)鄰接點(diǎn)的操作FirstAdjVex(G,v);Next23插入或刪除頂點(diǎn)InsertVex(&G,v);
//在圖G中增添新頂點(diǎn)v。DeleteVex(&G,v);//刪除G中頂點(diǎn)v及其相關(guān)的弧。插入或刪除頂點(diǎn)InsertVex(&G,v);Delet24插入和刪除弧InsertArc(&G,v,w);//在G中增添弧<v,w>,若G是無(wú)向的,//則還增添對(duì)稱弧<w,v>。DeleteArc(&G,v,w);
//在G中刪除弧<v,w>,若G是無(wú)向的,//則還刪除對(duì)稱弧<w,v>。插入和刪除弧InsertArc(&G,v,w);Del25遍歷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一次且僅一次。遍歷DFSTraverse(G,v,Visit()267.2圖的存儲(chǔ)表示一、圖的數(shù)組(鄰接矩陣)存儲(chǔ)表示二、圖的鄰接表存儲(chǔ)表示三、有向圖的十字鏈表存儲(chǔ)表示四、無(wú)向圖的鄰接多重表存儲(chǔ)表示7.2圖的存儲(chǔ)表示一、圖的數(shù)組(鄰接矩陣)存儲(chǔ)表示二、圖27Aij={0(i,j)VR1(i,j)VR一、圖的數(shù)組(鄰接矩陣)存儲(chǔ)表示BACDFE定義:矩陣的元素為Aij={0(i,j)VR1(i,j)VR一、圖28有向圖的鄰接矩陣為非對(duì)稱矩陣ABECF有向圖的鄰接矩陣為非對(duì)稱矩陣ABECF29typedefstructArcCell{//弧的定義VRTypeadj;//VRType是頂點(diǎn)關(guān)系類型。//對(duì)無(wú)權(quán)圖,用1或0表示相鄰否;//對(duì)帶權(quán)圖,則為權(quán)值類型。InfoType*info;//該弧相關(guān)信息的指針}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedefstructArcCell{//弧的30typedefstruct{//圖的定義VertexType//頂點(diǎn)信息vexs[MAX_VERTEX_NUM];AdjMatrixarcs;//弧的信息
intvexnum,arcnum;//頂點(diǎn)數(shù),弧數(shù)GraphKindkind;//圖的種類標(biāo)志
}MGraph;typedefstruct{//圖的定義310A141B0452C353D254E015F123BACDFE二、圖的鄰接表存儲(chǔ)表示0A14BACDFE二、圖的32142301201234ABCDE有向圖的鄰接表ABECF可見(jiàn),在有向圖的鄰接表中不易找到指向該頂點(diǎn)的弧BECD有向圖的逆鄰接表ABCDE30342001234在有向圖的鄰接表中,對(duì)每個(gè)頂點(diǎn),鏈接的是指向該頂點(diǎn)的弧。ABECD有向圖的逆鄰接表A303420034typedefstructArcNode{
intadjvex;//該弧所指向的頂點(diǎn)的位置
structArcNode*nextarc;//指向下一條弧的指針I(yè)nfoType*info;//該弧相關(guān)信息的指針}ArcNode;adjvexnextarcinfo弧的結(jié)點(diǎn)結(jié)構(gòu)typedefstructArcNode{adjv35typedefstructVNode{
VertexTypedata;//頂點(diǎn)信息ArcNode*firstarc;//指向第一條依附該頂點(diǎn)的弧
}VNode,AdjList[MAX_VERTEX_NUM];datafirstarc頂點(diǎn)的結(jié)點(diǎn)結(jié)構(gòu)typedefstructVNode{data36typedefstruct{
AdjListvertices;
intvexnum,arcnum;
intkind;//圖的種類標(biāo)志}ALGraph;圖的結(jié)構(gòu)定義typedefstruct{圖的結(jié)構(gòu)定義37三、有向圖的十字鏈表存儲(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;三、有向圖的十字鏈表存儲(chǔ)表示弧的結(jié)點(diǎn)結(jié)構(gòu)弧尾頂點(diǎn)位置弧頭38頂點(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;頂點(diǎn)的結(jié)點(diǎn)結(jié)構(gòu)頂點(diǎn)信息數(shù)據(jù)指向該頂點(diǎn)39typedefstruct{VexNodexlist[MAX_VERTEX_NUM];//頂點(diǎn)結(jié)點(diǎn)(表頭向量)
intvexnum,arcnum;//有向圖的當(dāng)前頂點(diǎn)數(shù)和弧數(shù)}OLGraph;有向圖的結(jié)構(gòu)表示(十字鏈表)typedefstruct{有向圖的結(jié)構(gòu)表示(十字鏈表40四、無(wú)向圖的鄰接多重表存儲(chǔ)表示typedefstructEbox{VisitIfmark;//訪問(wèn)標(biāo)記
intivex,jvex;//該邊依附的兩個(gè)頂點(diǎn)的位置
structEBox*ilink,*jlink;InfoType*info;//該邊信息指針}EBox;邊的結(jié)構(gòu)表示四、無(wú)向圖的鄰接多重表存儲(chǔ)表示typedefstruct41typedefstruct{//鄰接多重表
VexBoxadjmulist[MAX_VERTEX_NUM];
intvexnum,edgenum;
}AMLGraph;頂點(diǎn)的結(jié)構(gòu)表示typedefstructVexBox{VertexTypedata;EBox*firstedge;//指向第一條依附該頂點(diǎn)的邊}VexBox;無(wú)向圖的結(jié)構(gòu)表示typedefstruct{//鄰接多重表頂點(diǎn)的結(jié)427.3圖的遍歷
從圖中某個(gè)頂點(diǎn)出發(fā)游歷圖,訪遍圖中其余頂點(diǎn),并且使圖中的每個(gè)頂點(diǎn)僅被訪問(wèn)一次的過(guò)程。深度優(yōu)先搜索廣度優(yōu)先搜索遍歷應(yīng)用舉例7.3圖的遍歷從圖中某個(gè)頂點(diǎn)出發(fā)游歷圖,訪43深度優(yōu)先搜索DFS
(DepthFirstSearch)深度優(yōu)先搜索的示例ACDEGBFIHACDEGBFIH123456789123456789前進(jìn)回退深度優(yōu)先搜索過(guò)程深度優(yōu)先生成樹(shù)深度優(yōu)先搜索DFS(DepthFirstSearch)44DFS
在訪問(wèn)圖中某一起始頂點(diǎn)v
后,由
v
出發(fā),訪問(wèn)它的任一鄰接頂點(diǎn)
w1;再?gòu)膚1出發(fā),訪問(wèn)與w1鄰
接但還沒(méi)有訪問(wèn)過(guò)的頂點(diǎn)w2;然后再?gòu)膚2出發(fā),進(jìn)行類似的訪問(wèn),…如此進(jìn)行下去,直至到達(dá)所有的鄰接頂點(diǎn)都被訪問(wèn)過(guò)的頂點(diǎn)u為止。接著,退回一步,退到前一次剛訪問(wèn)過(guò)的頂點(diǎn),看是否還有其它沒(méi)有被訪問(wèn)的鄰接頂點(diǎn)。如果有,則訪問(wèn)此頂點(diǎn),之后再?gòu)拇隧旤c(diǎn)出發(fā),進(jìn)行與前述類似的訪問(wèn);如果沒(méi)有,就再退回一步進(jìn)行搜索。重復(fù)上述過(guò)程,直到連通圖中所有頂點(diǎn)都被訪問(wèn)過(guò)為止。DFS在訪問(wèn)圖中某一起始頂點(diǎn)v后,由v出發(fā),45圖的深度優(yōu)先搜索算法template<classT,classE>voidDFS(Graph<T,E>&G,constT&v){//從頂點(diǎn)v出發(fā)對(duì)圖G進(jìn)行深度優(yōu)先遍歷的主過(guò)程inti,loc,n=G.NumberOfVertices();//頂點(diǎn)個(gè)數(shù)bool*visited=newbool[n];//創(chuàng)建輔助數(shù)組 for(i=0;i<n;i++)visited
[i]=false;
//輔助數(shù)組visited初始化
loc=G.getVertexPos(v);
DFS(G,loc,visited);//從頂點(diǎn)0開(kāi)始深度優(yōu)先搜索 delete[]visited; //釋放visited};圖的深度優(yōu)先搜索算法template<classT,cl46template<classT,classE>voidDFS(Graph<T,E>&G,intv,boolvisited[]){cout<<G.getValue(v)<<'';//訪問(wèn)頂點(diǎn)v
visited[v]=true; //作訪問(wèn)標(biāo)記intw=G.getFirstNeighbor(v);//第一個(gè)鄰接頂點(diǎn) while(w!=-1){ //若鄰接頂點(diǎn)w存在 if(!visited[w])DFS(G,w,visited);
//若w未訪問(wèn)過(guò),遞歸訪問(wèn)頂點(diǎn)w
w=G.getNextNeighbor(v,w);//下一個(gè)鄰接頂點(diǎn)}};template<classT,classE>47廣度優(yōu)先搜索BFS
(BreadthFirstSearch)廣度優(yōu)先搜索的示例廣度優(yōu)先搜索過(guò)程廣度優(yōu)先生成樹(shù)ACDEGBFIHACDEGBFH123456789123456789I廣度優(yōu)先搜索BFS(BreadthFirstSearc48BFS在訪問(wèn)了起始頂點(diǎn)v之后,由v出發(fā),依次訪問(wèn)v的各個(gè)未被訪問(wèn)過(guò)的鄰接頂點(diǎn)w1,w2,…,wt,然后再順序訪問(wèn)w1,w2,…,wt的所有還未被訪問(wèn)過(guò)的鄰接頂點(diǎn)。再?gòu)倪@些訪問(wèn)過(guò)的頂點(diǎn)出發(fā),再訪問(wèn)它們的所有還未被訪問(wèn)過(guò)的鄰接頂點(diǎn),…如此做下去,直到圖中所有頂點(diǎn)都被訪問(wèn)到為止。廣度優(yōu)先搜索是一種分層的搜索過(guò)程,每向前走一步可能訪問(wèn)一批頂點(diǎn),不像深度優(yōu)先搜索那樣有往回退的情況。因此,廣度優(yōu)先搜索不是一個(gè)遞歸的過(guò)程。BFS在訪問(wèn)了起始頂點(diǎn)v之后,由v出發(fā),依次訪問(wèn)49
從圖中某個(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)先搜索遍歷從圖中某個(gè)頂點(diǎn)V0出發(fā),訪問(wèn)此頂點(diǎn),然后依次50Vw1SG1SG2SG3W1、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)先搜索遍歷。w2w3w2Vw1SG1SG2SG3W1、W2和W3均為V的鄰接點(diǎn)51從上頁(yè)的圖解可見(jiàn):1.從深度優(yōu)先搜索遍歷連通圖的過(guò)程類似于樹(shù)的先根遍歷;解決的辦法是:為每個(gè)頂點(diǎn)設(shè)立一個(gè)“訪問(wèn)標(biāo)志visited[w]”。2.如何判別V的鄰接點(diǎn)是否被訪問(wèn)?從上頁(yè)的圖解可見(jiàn):1.從深度優(yōu)先搜索遍歷連通圖的過(guò)程類似于52voidDFS(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}//DFSvoidDFS(GraphG,intv){53首先將圖中每個(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)先搜索遍歷首先將圖中每個(gè)頂點(diǎn)的訪問(wèn)標(biāo)志設(shè)為FALSE54voidDFSTraverse(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}voidDFSTraverse(GraphG,55abchdekfgFFFFFFFFFTTTTTTTTTachdkfebgachkfedbg訪問(wèn)標(biāo)志:訪問(wèn)次序:例如:012345678abchdekfgFFFFFF56二、廣度優(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。w1Vw2w7w6w3w8w5w4二、廣度優(yōu)先搜索遍歷圖Vw1w8w3w7w6w2w5w4對(duì)連57從圖中的某個(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)到為止。從圖中的某個(gè)頂點(diǎn)V0出發(fā),并在訪問(wèn)此頂點(diǎn)之后依次訪問(wèn)58
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……voidBFSTraverse(GraphG,……59visited[u]=TRUE;Visit(u);//訪問(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}//whilevisited[u]=TRUE;Visit(u);60三、遍歷應(yīng)用舉例1.求一條從頂點(diǎn)i到頂點(diǎn)s的簡(jiǎn)單路徑2.
求兩個(gè)頂點(diǎn)之間的一條路徑長(zhǎng)度最短的路徑三、遍歷應(yīng)用舉例1.求一條從頂點(diǎn)i到頂點(diǎn)s的2.611.
求一條從頂點(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,1.求一條從頂點(diǎn)i到頂點(diǎn)s的簡(jiǎn)單路徑abchde621.從頂點(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)。1.從頂點(diǎn)i到頂點(diǎn)s,若存在路徑,則從頂點(diǎn)i出63voidDFSearch(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
}voidDFSearch(intv,ints,c642.
求兩個(gè)頂點(diǎn)之間的一條路徑長(zhǎng)度最短的路徑
若兩個(gè)頂點(diǎn)之間存在多條路徑,則其中必有一條路徑長(zhǎng)度最短的路徑。如何求得這條路徑?2.求兩個(gè)頂點(diǎn)之間的一條路徑若兩個(gè)頂點(diǎn)之間存在多條65abchdekfg因此,求路徑長(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)度”漸增的次序。abchdekfg因此,求路徑長(zhǎng)度最短的路徑可以基于廣度優(yōu)先66例如:求下圖中頂點(diǎn)3至頂點(diǎn)5的一條最短路徑。鏈隊(duì)列的狀態(tài)如下所示:
312475
Q.front
Q.rear321475689例如:求下圖中頂點(diǎn)3至頂點(diǎn)5的一條最短路徑。鏈隊(duì)列的671)將鏈隊(duì)列的結(jié)點(diǎn)改為“雙鏈”結(jié)點(diǎn)。即結(jié)點(diǎn)中包含next和priou兩個(gè)指針;2)修改入隊(duì)列的操作。插入新的隊(duì)尾結(jié)點(diǎn)時(shí),令其priou域的指針指向剛剛出隊(duì)列的結(jié)點(diǎn),即當(dāng)前的隊(duì)頭指針?biāo)附Y(jié)點(diǎn);3)修改出隊(duì)列的操作。出隊(duì)列時(shí),僅移動(dòng)隊(duì)頭指針,而不將隊(duì)頭結(jié)點(diǎn)從鏈表中刪除。1)將鏈隊(duì)列的結(jié)點(diǎn)改為“雙鏈”結(jié)點(diǎn)。即2)修改入隊(duì)列的操68typedef
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->priou=Q.front
Q.rear->next=p;Q.rear=p;}voidDeQueue(LinkQueue&Q,QelemType&e){
Q.front=Q.front->next;e=Q.front->data}typedefDuLinkListQueuePtr;697.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)題:7.4(連通網(wǎng)的)最小生成樹(shù)假設(shè)要在n個(gè)70構(gòu)造網(wǎng)的一棵最小生成樹(shù),即:在e條帶權(quán)的邊中選取n-1條邊(不構(gòu)成回路),使“權(quán)值之和”為最小。算法二:(克魯斯卡爾算法)該問(wèn)題等價(jià)于:算法一:(普里姆算法)構(gòu)造網(wǎng)的一棵最小生成樹(shù),即:在e71
取圖中任意一個(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-1個(gè)頂點(diǎn)為止。普里姆算法的基本思想:取圖中任意一個(gè)頂點(diǎn)v作為生成樹(shù)的根,之后往生成樹(shù)72abcdegf例如:195141827168213ae12dcbgf7148531621所得生成樹(shù)權(quán)值和=14+8+3+5+16+21=67abcdegf例如:195141827168213ae12d73在生成樹(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)滿足下列條件:在生成樹(shù)的構(gòu)造過(guò)程中,圖中n個(gè)頂點(diǎn)分74設(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];設(shè)置一個(gè)輔助數(shù)組,對(duì)當(dāng)前V-U集中的每個(gè)頂點(diǎn),記錄和75abcdegf195141827168213ae12dcb7aaa19141814例如:e12ee8168d3dd7213c55abcdegf195141827168213ae12dcb776voidMiniSpanTree_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);voidMiniSpanTree_P(MGraphG,77
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};
k=minimum(closedge);78具體做法:先構(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)值盡可能地小??唆斔箍査惴ǖ幕舅枷耄壕唧w做法:先構(gòu)造一個(gè)只含n個(gè)頂點(diǎn)的子圖SG,然后從權(quán)79abcdegf195141827168213ae12dcbgf7148531621例如:7121819abcdegf195141827168213ae12dcbg80算法描述:構(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++;}算法描述:構(gòu)造非連通圖ST=(V,{});81普里姆算法克魯斯卡爾算法時(shí)間復(fù)雜度O(n2)O(eloge)稠密圖稀疏圖算法名適應(yīng)范圍比較兩種算法普里姆算法克魯斯卡爾算法時(shí)間復(fù)雜度O(n2)O(eloge)827.5重(雙)連通圖和關(guān)節(jié)點(diǎn)
若從一個(gè)連通圖中刪去任何一個(gè)頂點(diǎn)及其相關(guān)聯(lián)的邊,它仍為一個(gè)連通圖的話,則該連通圖被稱為重(雙)連通圖。問(wèn)題:7.5重(雙)連通圖若從一個(gè)連通圖中刪去任83
若連通圖中的某個(gè)頂點(diǎn)和其相關(guān)聯(lián)的邊被刪去之后,該連通圖被分割成兩個(gè)或兩個(gè)以上的連通分量,則稱此頂點(diǎn)為關(guān)節(jié)點(diǎn)。沒(méi)有關(guān)節(jié)點(diǎn)的連通圖為雙連通圖。如何判別給定的連通圖是否是雙連通圖?若連通圖中的某個(gè)頂點(diǎn)和其相關(guān)沒(méi)有關(guān)節(jié)點(diǎn)的連通84ahgcbfdeabcdefgh1234567833111111例如:下列連通圖中,頂點(diǎn)
a
和頂點(diǎn)c
是關(guān)節(jié)點(diǎn)深度優(yōu)先生成樹(shù)ahgcbfdeabcdefgh1234567833111185關(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)分析。關(guān)節(jié)點(diǎn)有何特征?假設(shè)從某個(gè)頂點(diǎn)V0出發(fā)對(duì)連通圖進(jìn)行深86
若生成樹(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)。若生成樹(shù)的根結(jié)點(diǎn),有兩個(gè)或兩個(gè)以上的分支,則此頂點(diǎn)(生成樹(shù)87對(duì)上述兩個(gè)判定準(zhǔn)則在算法中如何實(shí)現(xiàn)?對(duì)上述兩個(gè)判定準(zhǔn)則在算法中如何實(shí)現(xiàn)?881)設(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)1)設(shè)V0為深度優(yōu)先遍歷的出發(fā)點(diǎn)892)定義函數(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)。2)定義函數(shù):90對(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]?對(duì)深度優(yōu)先遍歷算法作如下修改:1.visited[v]的值改91for(p=G.vertices[v0].firstarc;p;p=p->nextarc){
}voidDFSArticul(ALGraphG,intv0){//從第v0個(gè)頂點(diǎn)出發(fā)深度優(yōu)先遍歷圖G,
//查找并輸出關(guān)節(jié)點(diǎn)}//DFSArticulmin=visited[v0]=++count;//v0是第count個(gè)訪問(wèn)的頂點(diǎn),并設(shè)low[v0]的初值為min
//檢查v0的每個(gè)鄰接點(diǎn)low[v0]=min;for(p=G.vertices[v0].firstarc;92
w=p->adjvex;//w為v0的鄰接頂點(diǎn)
if(visited[w]==0){//w未曾被訪問(wèn)DFSArticul(G,w);//返回前求得low[w]
}
else//w是回邊上的頂點(diǎn)if(low[w]<min)min=low[w];
if(low[w]>=visited[v0])
printf(v0,G.vertices[v0].data);
//輸出關(guān)節(jié)點(diǎn)if(visited[w]<min)min=visited[w];w=p->adjvex;//w為v0937.6兩點(diǎn)之間的
最短路徑問(wèn)題求從某個(gè)源點(diǎn)到其余各點(diǎn)的最短路徑每一對(duì)頂點(diǎn)之間的最短路徑
7.6兩點(diǎn)之間的
最短路徑問(wèn)題求從某個(gè)源點(diǎn)到其94求從源點(diǎn)到其余各點(diǎn)的最短路徑的算法的基本思想:依最短路徑的長(zhǎng)度遞增的次序求得各條路徑源點(diǎn)v1…其中,從源點(diǎn)到頂點(diǎn)v的最短路徑是所有最短路徑中長(zhǎng)度最短者。v2求從源點(diǎn)到其余各點(diǎn)的最短路徑的算法的基本思想:95在這條路徑上,必定只含一條弧,并且這條弧的權(quán)值最小。下一條路徑長(zhǎng)度次短的最短路徑的特點(diǎn):路徑長(zhǎng)度最短的最短路徑的特點(diǎn):它只可能有兩種情況:或者是直接從源點(diǎn)到該點(diǎn)(只含一條弧);或者是從源點(diǎn)經(jīng)過(guò)頂點(diǎn)v1,再到達(dá)該頂點(diǎn)(由兩條弧組成)。在這條路徑上,必定只含一條弧,并且這條弧的權(quán)值最小。96其余最短路徑的特點(diǎn):再下一條路徑長(zhǎng)度次短的最短路徑的特點(diǎn):它可能有三種情況:或者是直接從源點(diǎn)到該點(diǎn)(只含一條弧);或者是從源點(diǎn)經(jīng)過(guò)頂點(diǎn)v1,再到達(dá)該頂點(diǎn)(由兩條弧組成);或者是從源點(diǎn)經(jīng)過(guò)頂點(diǎn)v2,再到達(dá)該頂點(diǎn)。它或者是直接從源點(diǎn)到該點(diǎn)(只含一條弧);或者是從源點(diǎn)經(jīng)過(guò)已求得最短路徑的頂點(diǎn),再到達(dá)該頂點(diǎn)。其余最短路徑的特點(diǎn):再下一條路徑長(zhǎng)度次短的最短路徑的特點(diǎn):97求最短路徑的迪杰斯特拉算法:一般情況下,Dist[k]=<源點(diǎn)到頂點(diǎn)k的弧上的權(quán)值>或者=<源點(diǎn)到其它頂點(diǎn)的路徑長(zhǎng)度>
+<其它頂點(diǎn)到頂點(diǎn)k的弧上的權(quán)值>。
設(shè)置輔助數(shù)組Dist,其中每個(gè)分量Dist[k]表示
當(dāng)前所求得的從源點(diǎn)到其余各頂點(diǎn)k的最短路徑。求最短路徑的迪杰斯特拉算法:一般情況下,設(shè)置輔助數(shù)組Di981)在所有從源點(diǎn)出發(fā)的弧中選取一條權(quán)值最小的弧,即為第一條最短路徑。2)修改其它各頂點(diǎn)的Dist[k]值。假設(shè)求得最短路徑的頂點(diǎn)為u,若Dist[u]+G.arcs[u][k]<Dist[k]則將Dist[k]改為Dist[u]+G.arcs[u][k]。V0和k之間存在弧V0和k之間不存在弧其中的最小值即為最短路徑的長(zhǎng)度。1)在所有從源點(diǎn)出發(fā)的弧中選取一條權(quán)值最小的弧,即為第一條最99求每一對(duì)頂點(diǎn)之間的最短路徑弗洛伊德算法的基本思想是:從vi到vj的所有可能存在的路徑中,選出一條長(zhǎng)度最短的路徑。求每一對(duì)頂點(diǎn)之間的最短路徑弗洛伊德算法的基本思想是:從100若<vi,vj>存在,則存在路徑{vi,vj}//路徑中不含其它頂點(diǎn)若<vi,v1>,<v1,vj>存在,則存在路徑{vi,v1,vj}//路徑中所含頂點(diǎn)序號(hào)不大于1若{vi,…,v2},{v2,…,vj}存在,則存在一條路徑{vi,…,v2,…vj}//路徑中所含頂點(diǎn)序號(hào)不大于2…依次類推,則vi至vj的最短路徑應(yīng)是上述這些路徑中,路徑長(zhǎng)度最小者。若<vi,vj>存在,則存在路徑{vi,vj}依次1017.7拓?fù)渑判?/p>
問(wèn)題:
假設(shè)以有向圖表示一個(gè)工程的施工圖或程序的數(shù)據(jù)流圖,則圖中不允許出現(xiàn)回路。
檢查有向圖中是否存在回路的方法之一,是對(duì)有向圖進(jìn)行拓?fù)渑判颉?.7拓?fù)渑判騿?wèn)題:假設(shè)以有向圖表示一個(gè)102何謂“拓?fù)渑判颉???duì)有向圖進(jìn)行如下操作:
按照有向圖給出的次序關(guān)系,將圖中頂點(diǎn)排成一個(gè)線性序列,對(duì)于有向圖中沒(méi)有限定次序關(guān)系的頂點(diǎn),則可以人為加上任意的次序關(guān)系。何謂“拓?fù)渑判颉???duì)有向圖進(jìn)行如下操作:按照有向圖給103例如:對(duì)于下列有向圖BDAC可求得拓?fù)溆行蛐蛄校?/p>
ABCD
或
ACBD由此所得頂點(diǎn)的線性序列稱之為拓?fù)溆行蛐蛄欣纾簩?duì)于下列有向圖BDAC可求得拓?fù)溆行蛐蛄校河纱怂庙旤c(diǎn)104BDAC反之,對(duì)于下列有向圖不能求得它的拓?fù)溆行蛐蛄?。因?yàn)閳D中存在一個(gè)回路{B,C,D}BDAC反之,對(duì)于下列有向圖不能求得它的拓?fù)溆行蛐蛄小R驗(yàn)閳D105如何進(jìn)行拓?fù)渑判??一、從有向圖中選取一個(gè)沒(méi)有前驅(qū)的頂點(diǎn),并輸出之;
重復(fù)上述兩步,直至圖空,或者圖不空但找不到無(wú)前驅(qū)的頂點(diǎn)為止。二、從有向圖中刪去此頂點(diǎn)以及所
有以它為尾的??;如何進(jìn)行拓?fù)渑判??一、從有向圖中選取一個(gè)沒(méi)有前驅(qū)106abcghdfeabhcdgfe在算法中需要用定量的描述替代定性的概念
沒(méi)有前驅(qū)的頂點(diǎn)入度為零的頂點(diǎn)刪除頂點(diǎn)及以它為尾的弧弧頭頂點(diǎn)的入度減1abcghdfeabhcdgfe在算法中需要用定量的描述替代107取入度為零的頂點(diǎn)v;while(v<>0){
printf(v);++m;w:=FirstAdj(v);
while(w<>0){inDegree[w]--;w:=nextAdj(v,w);
}取下一個(gè)入度為零的頂點(diǎn)v;}ifm<nprintf(“圖中有回路”);算法描述取入度為零的頂點(diǎn)v;算法描述108為避免每次都要搜索入度為零的頂點(diǎn),在算法中設(shè)置一個(gè)“?!保员4妗叭攵葹榱恪钡捻旤c(diǎn)。CountInDegree(G,indegree);//對(duì)各頂點(diǎn)求入度InitStack(S);for(i=0;i<G.vexnum;++i)
if(!indegree[i])Push(S,i);//入度為零的頂點(diǎn)入棧為避免每次都要搜索入度為零的頂點(diǎn),Count109count=0;//對(duì)輸出頂點(diǎn)計(jì)數(shù)while(!EmptyStack(S)){
Pop(S,v);++count;printf(v);
for(w=FirstAdj(v);w;w=NextAdj(G,v,w)){
--indegree(w);//弧頭頂點(diǎn)的入度減一
if(!indegree[w])Push(S,w);
//新產(chǎn)生的入度為零的頂點(diǎn)入棧}}if(count<G.vexnum)printf(“圖中有回路”)count=0;//對(duì)輸出頂點(diǎn)計(jì)數(shù)1107.8關(guān)鍵路徑問(wèn)題:
假設(shè)以有向網(wǎng)表示一個(gè)施工流圖,弧上的權(quán)值表示完成該項(xiàng)子工程所需時(shí)間。問(wèn):哪些子工程項(xiàng)是“關(guān)鍵工程”?即:哪些子工程項(xiàng)將影響整個(gè)工程的完成期限的。7.8關(guān)鍵路徑問(wèn)題:假設(shè)以有向網(wǎng)表示一個(gè)111abcdefghk64521187244例如:“關(guān)鍵活動(dòng)”指的是:該弧上的權(quán)值增加
將使有向圖上的最長(zhǎng)路徑的長(zhǎng)度增加。整個(gè)工程完成的時(shí)間為:從有向圖的源點(diǎn)到匯點(diǎn)的最長(zhǎng)路徑。源點(diǎn)匯點(diǎn)6174abcdefghk64521187244例如:“關(guān)鍵活動(dòng)”指112
如何求關(guān)鍵活動(dòng)?“事件(頂點(diǎn))”的最早發(fā)生時(shí)間ve(j)ve(j)=從源點(diǎn)到頂點(diǎn)j的最長(zhǎng)路徑長(zhǎng)度;“事件(頂點(diǎn))”的最遲發(fā)生時(shí)間vl(k)vl(k)=從頂點(diǎn)k到匯點(diǎn)的最短路徑長(zhǎng)度。如何求關(guān)鍵活動(dòng)?“事件(頂點(diǎn))”的最早發(fā)生時(shí)間ve(113
假設(shè)第i條弧為<j,k>則對(duì)第i項(xiàng)活動(dòng)言“活動(dòng)(弧)”的最早開(kāi)始時(shí)間ee(i)ee(i)=ve(j);“活動(dòng)(弧)”的最遲開(kāi)始時(shí)間el(i)el(i)=vl(k)–dut(<j,k>);假設(shè)第i條弧為<j,k>114
事件發(fā)生時(shí)間的計(jì)算公式:ve(源點(diǎn))=0;ve(k)=Max{ve(j)+dut(<j,k>)}vl(匯點(diǎn))=ve(匯點(diǎn));vl(j)=Min{vl(k)–dut(<j,k>)}事件發(fā)生時(shí)間的計(jì)算公式:115abcdefghk6452118724400000000064571157151418181818181818181818161486610807拓?fù)溆行蛐蛄?a-d-f-c-b-e-h-g-kabcdefghk6452118724400000000061160645771514181814161078660000645777151414160236688710064577151418181416107866000064117
算法的實(shí)現(xiàn)要點(diǎn):顯然,求ve的順序應(yīng)該是按拓?fù)溆行虻拇涡颍?/p>
而求vl的順序應(yīng)該是按拓?fù)淠嫘虻拇涡?;因?yàn)橥負(fù)淠嫘蛐蛄屑礊橥負(fù)溆行蛐蛄械哪嫘蛄?,因此?yīng)該在拓?fù)渑判虻倪^(guò)程中,另設(shè)一個(gè)“?!庇浵峦?fù)溆行蛐蛄小K惴ǖ膶?shí)現(xiàn)要點(diǎn):顯然,求ve的順序應(yīng)該是按拓?fù)溆行虻拇涡颍?181.熟悉圖的各種存儲(chǔ)結(jié)構(gòu)及其構(gòu)造算法,了解實(shí)際問(wèn)題的求解效率與采用何種存儲(chǔ)結(jié)構(gòu)和算法有密切聯(lián)系。2.熟練掌握?qǐng)D的兩種搜索路徑的遍歷:遍歷的邏輯定義、深度優(yōu)先搜索和廣度優(yōu)先搜索的算法。在學(xué)習(xí)中應(yīng)注意圖的遍歷算法與樹(shù)的遍歷算法之間的類似和差異。1.熟悉圖的各種存儲(chǔ)結(jié)構(gòu)及其構(gòu)造算法,了解實(shí)際問(wèn)題的求解119
3.應(yīng)用圖的遍歷算法求解各種簡(jiǎn)單路徑問(wèn)題。4.理解教科書(shū)中討論的各種圖的算法。3.應(yīng)用圖的遍歷算法求解各種簡(jiǎn)單路徑問(wèn)題。1207.1抽象數(shù)據(jù)類型圖的定義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)鍵路徑7.1抽象數(shù)據(jù)類型圖的定義7.2圖的存儲(chǔ)表示7.3圖的121圖的基本概念圖定義圖是由頂點(diǎn)集合(vertex)及頂點(diǎn)間的關(guān)系集合組成的一種數(shù)據(jù)結(jié)構(gòu):
Graph=(V,E)
其中
V={x|x某個(gè)數(shù)據(jù)對(duì)象}
是頂點(diǎn)的有窮非空集合;
E={(x,y)|x,y
V}
或
E={<x,y>|x,y
V&&Path(x,y)}
是頂點(diǎn)之間關(guān)系的有窮集合,也叫做邊(edge)集合。Path(x,y)表示從x到y(tǒng)的一條單向通路,它是有方向的。圖的基本概念圖定義圖是由頂點(diǎn)集合(vertex)及頂點(diǎn)122
有向圖與無(wú)向圖在有向圖中,頂點(diǎn)對(duì)<x,y>是有序的。在無(wú)向圖中,頂點(diǎn)對(duì)(x,y)是無(wú)序的。完全圖若有
n個(gè)頂點(diǎn)的無(wú)向圖有n(n-1)/2條邊,則此圖為完全無(wú)向圖。有
n個(gè)頂點(diǎn)的有向圖有n(n-1)條邊,則此圖為完全有向圖。00001111222265433有向圖與無(wú)向圖在有向圖中,頂點(diǎn)對(duì)<x,y>123
鄰接頂點(diǎn)如果
(u,v)是E(G)中的一條邊,則稱u與v互為鄰接頂點(diǎn)。子圖設(shè)有兩個(gè)圖G=(V,E)和G'=(V',E')。若V'V且E'E,則稱圖G'是圖G的子圖。權(quán)某些圖的邊具有與它相關(guān)的數(shù),稱之為權(quán)。這種帶權(quán)圖叫做網(wǎng)絡(luò)。子圖01230130123023鄰接頂點(diǎn)如果(u,v)是E(G)中的一124頂點(diǎn)的度一個(gè)頂點(diǎn)v的度是與它相關(guān)聯(lián)的邊的條數(shù)。記作TD(v)。在有向圖中,頂點(diǎn)的度等于該頂點(diǎn)的入度與出度之和。頂點(diǎn)v的入度是以v為終點(diǎn)的有向邊的條數(shù),記作
ID(v);頂點(diǎn)v的出度是以v為始點(diǎn)的有向邊的條數(shù),記作
OD(v)。路徑在圖G=(V,E)中,若從頂點(diǎn)
vi
出發(fā),沿一些邊經(jīng)過(guò)一些頂點(diǎn)
vp1,
vp2,…,
vpm,到達(dá)頂點(diǎn)vj。則稱頂點(diǎn)序列
(vi
vp1vp2...vpm
vj)
為從頂點(diǎn)vi到頂點(diǎn)
vj的路徑。它經(jīng)過(guò)的邊(vi,vp1)、(vp1,vp2)、...、(vpm,vj)應(yīng)是屬于E的邊。頂點(diǎn)的度一個(gè)頂點(diǎn)v的度是與它相關(guān)聯(lián)的邊的條數(shù)。記作TD(125路徑長(zhǎng)度非帶權(quán)圖的路徑長(zhǎng)度是指此路徑上邊的條數(shù)。帶權(quán)圖的路徑長(zhǎng)度是指路徑上各邊的權(quán)之和。簡(jiǎn)單路徑若路徑上各頂點(diǎn)v1,v2,...,vm
均不互相重復(fù),則稱這樣的路徑為簡(jiǎn)單路徑。回路若路徑上第一個(gè)頂點(diǎn)v1與最后一個(gè)頂點(diǎn)vm重合,則稱這樣的路徑為回路或環(huán)。012301230123路徑長(zhǎng)度非帶權(quán)圖的路徑長(zhǎng)度是指此路徑上邊的條數(shù)。帶權(quán)圖的126連通圖與連通分量在無(wú)向圖中,若從頂點(diǎn)v1到頂點(diǎn)v2有路徑,則稱頂點(diǎn)v1與v2是連通的。如果圖中任意一對(duì)頂點(diǎn)都是連通的,則稱此圖是連通圖。非連通圖的極大連通子圖叫做連通分量。強(qiáng)連通圖與強(qiáng)連通分量在有向圖中,若對(duì)于每一對(duì)頂點(diǎn)vi和vj,都存在一條從vi到vj和從vj到vi的路徑,則稱此圖是強(qiáng)連通圖。非強(qiáng)連通圖的極大強(qiáng)連通子圖叫做強(qiáng)連通分量。生成樹(shù)一個(gè)連通圖的生成樹(shù)是其極小連通子圖,在n個(gè)頂點(diǎn)的情形下,有
n-1條邊。連通圖與連通分量在無(wú)向圖中,若從頂點(diǎn)v1到頂點(diǎn)v2有127
圖是由一個(gè)頂點(diǎn)集V和一個(gè)弧集R構(gòu)成的數(shù)據(jù)結(jié)構(gòu)。Graph=(V,R)其中,VR={<v,w>|v,w∈V且P(v,w)}
<v,w>表示從v到w的一條弧,并稱v為弧頭,w為弧尾。
謂詞P(v,w)定義了弧<v,w>的意義或信息。圖的結(jié)構(gòu)定義:圖是由一個(gè)頂點(diǎn)集V和一個(gè)弧集R構(gòu)成的數(shù)據(jù)結(jié)構(gòu)。128
由于“弧”是有方向的,因此稱由頂點(diǎn)集和弧集構(gòu)成的圖為有向圖。
AB
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 個(gè)人食品訂購(gòu)合同(2024版)3篇
- 2024浙江房產(chǎn)買(mǎi)賣(mài)合同(含裝修標(biāo)準(zhǔn))3篇
- 老年智能手機(jī)課程設(shè)計(jì)
- 美食調(diào)料培訓(xùn)課程設(shè)計(jì)
- 高中微課課程設(shè)計(jì)
- 秋天 課程設(shè)計(jì)說(shuō)明
- 鐵路運(yùn)輸?shù)乩碚n程設(shè)計(jì)
- 陶藝非遺文化課程設(shè)計(jì)
- 自動(dòng)控制原理pid課程設(shè)計(jì)
- 遺傳基本定律的課程設(shè)計(jì)
- 《國(guó)有控股上市公司高管薪酬的管控研究》
- 餐飲業(yè)環(huán)境保護(hù)管理方案
- 人教版【初中數(shù)學(xué)】知識(shí)點(diǎn)總結(jié)-全面+九年級(jí)上冊(cè)數(shù)學(xué)全冊(cè)教案
- 食品安全分享
- 礦山機(jī)械設(shè)備安全管理制度
- 計(jì)算機(jī)等級(jí)考試二級(jí)WPS Office高級(jí)應(yīng)用與設(shè)計(jì)試題及答案指導(dǎo)(2025年)
- 造價(jià)框架協(xié)議合同范例
- 糖尿病肢端壞疽
- 心衰患者的個(gè)案護(hù)理
- 醫(yī)護(hù)人員禮儀培訓(xùn)
- 無(wú)人機(jī)飛行安全協(xié)議書(shū)
評(píng)論
0/150
提交評(píng)論