數(shù)據(jù)結(jié)構(gòu)與算法第6章圖結(jié)構(gòu)pot_第1頁(yè)
數(shù)據(jù)結(jié)構(gòu)與算法第6章圖結(jié)構(gòu)pot_第2頁(yè)
數(shù)據(jù)結(jié)構(gòu)與算法第6章圖結(jié)構(gòu)pot_第3頁(yè)
數(shù)據(jù)結(jié)構(gòu)與算法第6章圖結(jié)構(gòu)pot_第4頁(yè)
數(shù)據(jù)結(jié)構(gòu)與算法第6章圖結(jié)構(gòu)pot_第5頁(yè)
已閱讀5頁(yè),還剩103頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

救據(jù)輅相易算該

2褂;刻帶不

___第念*圖轄構(gòu)____

7、囹的基域概念

久畫的商儲(chǔ)方法

品囹的遍歷

么眩感樹(shù)和景小眩感樹(shù)

5、1向無(wú)環(huán)困及其應(yīng)用

6、獴短路往

1、囹的基本就念

7,7二天樹(shù)的定義

1、圖的定義

圖(Graph)由一個(gè)頂點(diǎn)集合Vn和一個(gè)邊(或者弧)集合En組成

,通常記為:G=(Vn,En),其中Vn中有n(n>0)個(gè)頂點(diǎn),E”中有e(

e>=0)條邊,且每一條邊都依附于V。中的兩個(gè)頂點(diǎn)看,寸(i,

j=l,2,---,n),該邊用頂點(diǎn)偶對(duì)來(lái)表示,記為(vj)。

圖6-1給出了一個(gè)圖的示例:

頂點(diǎn)集合:N={vl,v2,v3,v4,v5};

邊集合:E={(vl,v2),(vl,v4),(v2,v3),(v3,v4),

(v3,v5),(v2,v5)}

2.圖的相關(guān)術(shù)語(yǔ)》

⑴無(wú)命蹲

⑵有向圖

有向圖的邊用<Vj,Vj>表示;

v%,Vj>和<VjM>不是同一條邊;

有向邊也稱為弧,箭頭一端成為弧頭,另一端為弧尾。

例:圖6-2所示是一個(gè)有向圖G2。

表示為:

G2=(V2?E2)

V2={%"2尹3尹4}圖6-2有向圖G2

E2={<vt,v2>,<v1v3>,<v3,v4>,<v4,v1>}

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義4

(3)鄰接點(diǎn)、鄰接邊

(4)完全圖

⑸稠密圖、稀疏圖

⑹頂點(diǎn)的度、入度、出度

⑺邊的權(quán)、網(wǎng)圖

(8)路徑和路徑長(zhǎng)度

(9)回路、簡(jiǎn)單路徑、簡(jiǎn)單回路

(10)子圖

(11)連通的、連通圖、連通分量

(12)強(qiáng)連通圖、強(qiáng)連通分量

(13)連通圖(或子圖)的生成樹(shù)

(14)非連通圖的生成森林

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義5

7,2囹的基本據(jù)作

(1)CreatGraph(G):建立圖G的存儲(chǔ)。

⑵DestroyGraph(G):釋放圖G占用的存儲(chǔ)空間。

(3)GetVex(G,v):在圖G中找到頂點(diǎn)v,并返回頂點(diǎn)v的相關(guān)信息。

(4)PutVex(G,v,value):在圖G中找到頂點(diǎn)v,并將value值賦給頂

點(diǎn)V。

⑸InscrtVcx(G,v):在圖G中增添新頂點(diǎn)V。

(6)DeleteVex(G,v):在圖G中,刪除頂點(diǎn)v以及所有和頂點(diǎn)v相關(guān)

聯(lián)的邊或弧。

⑺InscrtArc(G,v,w):在圖G中增添一條從頂點(diǎn)v到頂點(diǎn)w的邊或弧

°2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義6

(8)DeleteArc(G,v,w):在圖G中刪除一條從頂點(diǎn)v到頂點(diǎn)w的邊或

弧。

(9)Traverse(G,v):在圖G中,從頂點(diǎn)v出發(fā)遍歷圖G。

(10)LocateVex(G,u):在圖G中找到頂點(diǎn)u,返回該頂點(diǎn)在圖中存

儲(chǔ)位置。

(11)FirstAdjVex(G,v):在圖G中,返回v的第一個(gè)鄰接點(diǎn)。若頂點(diǎn)

在G中沒(méi)有鄰接點(diǎn),則返回“空”。

(12)NextAdjVex(G,v,w):在圖G中,返回v的(相對(duì)于w的)下一

個(gè)鄰接點(diǎn)。若W是V的最后一個(gè)鄰接點(diǎn),則返回“空”。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義7

__蝎

需要注意的是:

在一個(gè)圖中,頂點(diǎn)是沒(méi)有先后次序的,但當(dāng)我們?cè)趯?duì)它的

存儲(chǔ)中確定了頂點(diǎn)的次序后,存儲(chǔ)中的頂點(diǎn)次序構(gòu)成了頂點(diǎn)之

間的相對(duì)次序。同樣的道理,對(duì)一個(gè)頂點(diǎn)的鄰接點(diǎn),也根據(jù)存

儲(chǔ)順序決定了第1個(gè)、第2個(gè)…。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義8

久畫的存儲(chǔ)方法

2/鄰接矩陣

1、鄰接矩陣的存儲(chǔ)思想

⑴圖中頂點(diǎn)順序存儲(chǔ);

⑵用一個(gè)n*n矩陣(設(shè)圖有n個(gè)頂點(diǎn))來(lái)存儲(chǔ)任意兩個(gè)頂

點(diǎn)之間邊的信息,也就是各頂點(diǎn)之間的鄰接關(guān)系。

1若(%,Vj)或<Vj,Vj>是E(G)中的邊

A[i]O]={

0若(v/j)或<%,3>不是E(G)中的邊

若G是帶權(quán)圖,則鄰接矩陣可定義為:

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義9

二/亞若(v/j)或v%,Vj>是E(G)中的邊

00

?;蛉?vi,v.)或v>不是E(G)中的邊

■其中,Wjj表示邊(胃*)或<%,¥>上的權(quán)值;8表示一個(gè)計(jì)算

機(jī)允許的、大于所有邊上權(quán)值的數(shù)。

用鄰接矩陣表示法表示的無(wú)向圖和網(wǎng)圖如下圖所示。

010r

A=1011

0100

JI00

f無(wú)向圖的鄰轆陣表示

「OO

963OO

9OO45OO

A=64OOOO7

35OOOO8

ipoOO78OO

Y網(wǎng)卻於陵矩陣表示

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義11

2、鄰接矩陣的表示

一用一個(gè)一維數(shù)組來(lái)存儲(chǔ)頂點(diǎn)信息;¥>

用一個(gè)二維數(shù)組存儲(chǔ)鄰接矩陣,用于表示頂點(diǎn)間相鄰關(guān)系;

⑴一般情況

若圖的頂點(diǎn)個(gè)數(shù)和邊的個(gè)數(shù)是一個(gè)變量時(shí),還需要留有足

夠的空間。故可將其形式描述如下:

#defineMaxVertexNum…/*定義能存儲(chǔ)的足夠大的頂點(diǎn)個(gè)數(shù)*/

typedefcharVertexType;/*VcrtcxType為頂點(diǎn)類型,設(shè)為字符型*/

typedefintEdgeType;/*EdgeType為邊的權(quán)值類型,設(shè)為整型*/

typedefstruct

{VertexTypevexs[MaxVertexNum];/*頂點(diǎn)表*/

EdgeTypeedges[MaxVertexNum][MaxVertexNum];/*eF接矩陣*/

intn,e;/*實(shí)際的頂點(diǎn)數(shù)和邊數(shù)*/

JMMGagh;數(shù)據(jù)結(jié)構(gòu)講義12

⑵簡(jiǎn)單情況

在大部分的應(yīng)用中,圖中的頂點(diǎn)個(gè)數(shù)和邊的個(gè)數(shù)常常是一個(gè)

已知的常量,不妨設(shè)為N和E,在這種情況下可以簡(jiǎn)化以上定義

為:

typedefcharVertexType;

typedefintEdgeType;

typedefstruct

{VertexTypevexs[N];/*頂點(diǎn)表*/

EdgeTypeedges[N][N];/*?F接矩陣*/

}MGragh;/*MGragh是以鄰接矩陣存儲(chǔ)的圖類型*/

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義13

一—_____._——.-—?

3、鄰接矩陣存儲(chǔ)方法的特點(diǎn)

①無(wú)向圖的鄰接矩陣一定是一個(gè)對(duì)稱矩陣。因此,在具體存放

鄰接矩陣時(shí)只需存放上(或下)三角矩陣的元素即可。

②對(duì)于無(wú)向圖,鄰接矩陣的第i行(或第i列)非零元素(或非8

元素)的個(gè)數(shù)正好是第i個(gè)頂點(diǎn)的度TD(v)。

③對(duì)于有向圖,鄰接矩陣的第i行(或第i列)非零元素(或非8

元素)的個(gè)數(shù)正好是第i個(gè)頂點(diǎn)的出度OD(v)(或入度ID(v))o

④用鄰接矩陣方法存儲(chǔ)圖,很容易確定圖中任意兩個(gè)頂點(diǎn)之間

是否有邊相連;但是,要確定圖中有多少條邊,則必須按行、

按列對(duì)每個(gè)元素進(jìn)行檢測(cè),所花費(fèi)的時(shí)間代價(jià)很大。這是用鄰

接矩陣存儲(chǔ)圖的局限性。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義14

4、需要說(shuō)明以下兩點(diǎn).一

(1)在圖中沒(méi)有一個(gè)特殊的頂點(diǎn)是“第一個(gè),第二個(gè)

…”,因此存儲(chǔ)時(shí)也是如此,頂點(diǎn)的存儲(chǔ)順序可以依實(shí)際問(wèn)

題的某個(gè)順序人為的來(lái)規(guī)定,一旦頂點(diǎn)的存儲(chǔ)順序確定,就

構(gòu)成了頂點(diǎn)之間的相對(duì)次序,鄰接矩陣一定要與其對(duì)應(yīng),除

了頂點(diǎn)數(shù)組的每個(gè)分量中的頂點(diǎn)信息域中存放的是頂點(diǎn)的信

息,其它地方存放的都是頂點(diǎn)的存儲(chǔ)序號(hào)。

(2)圖中的N個(gè)頂點(diǎn)依次存儲(chǔ)在頂點(diǎn)數(shù)組的[0]..[N-1]分

量中,稱0..N-1為各頂點(diǎn)的存儲(chǔ)序號(hào),簡(jiǎn)稱為頂點(diǎn)0,頂點(diǎn)

N-lo如不加說(shuō)明,在其它的存儲(chǔ)方法中也是如此。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義15

5、建立一個(gè)有向圖鄰接矩陣存儲(chǔ)的算法

【算法6-1】建立一個(gè)有向圖的鄰接矩陣存儲(chǔ)

voidCreateMGraph(IVIGraph*G)

{/*建立有向圖G的鄰接矩陣存儲(chǔ),N,E是圖的頂點(diǎn)個(gè)數(shù)和邊的個(gè)數(shù),

■nti,j,k,w;

charch;/*設(shè)圖的頂點(diǎn)信息為字符型*/

for(i=O;i<N;i++)scanf("%c”,&(G->vexs[i]));

/*輸入頂點(diǎn)信息,建立頂點(diǎn)表*/

for(i=O;i<N;i++)

for(j=O;j<N;j++)

G->edges[i][j]=O;/*初始化鄰接矩陣,

for(k=O;k<E;k++)

G->edges[i][j]=1;

/*若為無(wú)向圖,還要建立(j捋邊,即:G->edges[j][i]=1;*/

ZU1Z-H-/7JZ1口-II*7I/Xr10

22鄰接表

1、鄰接表的存儲(chǔ)思想

鄰接表(AdjacencyList)是圖的一種順序存儲(chǔ)與鏈?zhǔn)酱鎯?chǔ)結(jié)合

的存儲(chǔ)方法。鄰接表表示法類似于樹(shù)的孩子鏈表表示法。方法是

對(duì)于圖G中的每個(gè)頂點(diǎn)看,將所有鄰接于看的頂點(diǎn)Vj鏈成一個(gè)單鏈

表,這個(gè)單鏈表就稱為頂點(diǎn)看的鄰接表,再將所有點(diǎn)的鄰接表表

頭放到數(shù)組中,就構(gòu)成了圖的鄰接表。

下圖給出無(wú)向圖及對(duì)應(yīng)的鄰接表表示。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義17

4

序號(hào)vertexfiistedge

翱鄰糜表示

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義18

2、鄰接表的兩種結(jié)點(diǎn)結(jié)構(gòu)

頂點(diǎn)城朦甜旨針鄰接點(diǎn)域指針城

vertexfirstedgeadjvexnel

頂點(diǎn)表邊表

鄰接矩陣標(biāo)的結(jié)點(diǎn)結(jié)構(gòu)

頂點(diǎn)表的結(jié)點(diǎn)結(jié)構(gòu):由頂點(diǎn)域(vertex)和指向第一條鄰接

邊的指針域(firstedge)構(gòu)成。

邊表(即鄰接表)結(jié)點(diǎn)結(jié)構(gòu):由鄰接點(diǎn)域(adjvex)和指向下

一條鄰接邊的指針域(圖的next)構(gòu)成。對(duì)于網(wǎng)邊表需再增設(shè)一個(gè)

存儲(chǔ)邊上信息(如權(quán)值等)的域(inf。),網(wǎng)圖的邊表結(jié)構(gòu)如下

圖所示。鄰接點(diǎn)域邊上信息指針域

adjvexinfonext

網(wǎng)圖的邊超構(gòu)

2012年7月21日雙循循忸口乂19

J

3、鄰接表的形式描述

typedefstructnode

{intadjvex;/*鄰接點(diǎn)域*/

structnode*next;/*指向下一個(gè)鄰接點(diǎn)(或邊)的指針域*/

,一/*若要表示邊上信息,則應(yīng)增加相關(guān)數(shù)據(jù)域info*/

}EdgeNode;/*邊結(jié)點(diǎn)*/

typedefstructvnode

{VertexTypevertex;/*頂點(diǎn)域*/

EdgeNode*firstedge;/*第一條邊的指針*/

}VertexNode;/*頂點(diǎn)結(jié)點(diǎn)*/

VertexNodeAdjList[N];/*頂點(diǎn)結(jié)點(diǎn)向量*/

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義20

4、建立一^個(gè)有向圖鄰接表的算法

【算法6-2】建立一個(gè)有向圖的鄰接表存儲(chǔ)

voidCreateALGraph(VertexNodeAdjList[])

{/*建立有向圖的鄰接表存儲(chǔ),N,E是圖的頂點(diǎn)個(gè)數(shù)和邊的個(gè)數(shù)*/

inti,j,k;

EdgeNode*s;

for(i=0;i<N;i++)/*建立有n個(gè)頂點(diǎn)的頂點(diǎn)表*/

{scanf("%c",&(AdjList[i].vertex));/*讀入頂點(diǎn)信息*/

AdjList[i].firstedge=NULL;/*頂點(diǎn)的邊表頭指針設(shè)為空*/

)

for(k=0;k<E;k++)/*建立邊表*/

/*讀入邊的頂點(diǎn)序號(hào)對(duì)偶*/

{scanfC%d,%d",&i9&j);

s=(EdgeNode*)maHoc(siNeof(Ed9eNocle));/*新邊表結(jié)點(diǎn)s*/

s->adjvex=j;/*鄰接點(diǎn)序號(hào)為j*/

s->next=AdjList[i].firstedge;

/*將新邊表結(jié)點(diǎn)s插入到頂點(diǎn)vi的邊表頭部*/

AdjList[i].firstedge=s;

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義21

在建立鄰接表或逆鄰接表時(shí),若輸入的頂點(diǎn)信息即為頂點(diǎn)

的編號(hào),則建立鄰接表的復(fù)雜度為O(n+e),否則,需要通過(guò)

查找才能得到頂點(diǎn)在圖中位置,則時(shí)間復(fù)雜度為O(n-e)o

在鄰接表上容易找到任一頂點(diǎn)的第一個(gè)鄰接點(diǎn)和下一個(gè)鄰

接點(diǎn),但要判定任意兩個(gè)頂點(diǎn)(%和V,之間是否有邊或弧相連

,則需搜索第i個(gè)或第j個(gè)鏈表,因此,不及鄰接矩陣方便。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義22

5、鄰接表存儲(chǔ)方法的特點(diǎn)

(1)若無(wú)向圖中有n個(gè)頂點(diǎn)、c條邊,則它的鄰接表需n個(gè)頭結(jié)

點(diǎn)和2c個(gè)表結(jié)點(diǎn)。顯然,在邊稀疏(eV<n(n-1)/2)的情況下,用鄰

接表表示圖比鄰接矩陣節(jié)省存儲(chǔ)空間,當(dāng)和邊相關(guān)的信息較多時(shí)

更是如此。

(2)在無(wú)向圖的鄰接表中,頂點(diǎn)看的度恰為第i個(gè)鏈表中的結(jié)點(diǎn)

數(shù);而在有向圖中,第i個(gè)鏈表中的結(jié)點(diǎn)個(gè)數(shù)只是頂點(diǎn)看的出度,

為求人度,必須遍歷整個(gè)鄰接表。在所有鏈表中其鄰接點(diǎn)域的值

為i的結(jié)點(diǎn)的個(gè)數(shù)是頂點(diǎn)Vj的入度。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義23

6、有向圖的逆鄰接表一

若鄰接表的邊結(jié)點(diǎn)鏈表建立的是以治為頭的弧鏈表,這樣

的鄰接表稱為逆鄰接表。逆鄰接表便于確定頂點(diǎn)的入度或以

頂點(diǎn)X為頭的弧。

下圖所示為有向圖G2的鄰接表和逆鄰接表。

(a)W(b)逆避表

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義24

品畫的遍歷

圖的遍歷是指從圖中的任一頂點(diǎn)出發(fā),對(duì)圖中的所有頂點(diǎn)

訪問(wèn)一次且只訪問(wèn)一次。圖的遍歷是圖的一種基本操作,圖的

許多其它操作都是建立在遍歷操作的基礎(chǔ)之上。

由于圖結(jié)構(gòu)本身的復(fù)雜性,所以圖的遍歷操作也較復(fù)雜,

主要表現(xiàn)在以下四個(gè)方面:

①在圖結(jié)構(gòu)中,沒(méi)有一個(gè)“自然”的首結(jié)點(diǎn),圖中任意一

個(gè)頂點(diǎn)都可作為第一個(gè)被訪問(wèn)的結(jié)點(diǎn)。

②在非連通圖中,從一個(gè)頂點(diǎn)出發(fā),只能夠訪問(wèn)它所在的

連通分量上的所有頂點(diǎn),因此,還需考慮如何選取下一個(gè)出發(fā)

點(diǎn)以訪問(wèn)圖中其余的連通分量。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義25

③在圖結(jié)構(gòu)中,如果有回路存在,那么一個(gè)頂點(diǎn)被訪問(wèn)之后

,有可能沿回路又回到該頂點(diǎn)。

④在圖結(jié)構(gòu)中,一個(gè)頂點(diǎn)可以和其它多個(gè)頂點(diǎn)相連,當(dāng)這樣

的頂點(diǎn)訪問(wèn)過(guò)后,存在如何選取下一個(gè)要訪問(wèn)的頂點(diǎn)的問(wèn)題。

兩種遍歷方法:深度優(yōu)先搜索、廣度優(yōu)先搜索

3.1隆盛優(yōu)法搜索

深度優(yōu)先搜索(Depth_FisrstSearch)遍歷類似于樹(shù)的先根遍

歷,是樹(shù)的先根遍歷的推廣。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義26

1、深度優(yōu)先搜索的概念

假設(shè)初始狀態(tài)是圖中所有頂點(diǎn)未曾被訪問(wèn),則深度優(yōu)先搜

索可從圖中某個(gè)頂點(diǎn)發(fā)V出發(fā),訪問(wèn)此頂點(diǎn),然后依次從V的未被

訪問(wèn)的鄰接點(diǎn)出發(fā)深度優(yōu)先遍歷圖,直至圖中所有和V有路徑相

通的頂點(diǎn)都被訪問(wèn)到;若此時(shí)圖中尚有頂點(diǎn)未被訪問(wèn),則另選

圖中一個(gè)未曾被訪問(wèn)的頂點(diǎn)作起始點(diǎn),重復(fù)上述過(guò)程,直至圖

中所有頂點(diǎn)都被訪問(wèn)到為止。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義27

以下圖的無(wú)向圖G5為例,進(jìn)行圖的深度優(yōu)先搜索。必

假設(shè)從頂點(diǎn)%出發(fā)進(jìn)行搜索,在訪問(wèn)了頂點(diǎn)%之后,選擇鄰

接點(diǎn)V2。因?yàn)檠?未曾訪問(wèn),則從V2出發(fā)進(jìn)行搜索。依次類推,接著

從V4、Vg、V5出發(fā)進(jìn)行搜索。在訪問(wèn)了V5之后,由于V5的鄰接點(diǎn)

都已被訪問(wèn),則搜索回到V8o由于同樣的理由,搜索繼續(xù)回到V4

,V2直至V[,此時(shí)由于當(dāng)?shù)牧硪粋€(gè)鄰接點(diǎn)未被訪問(wèn),則搜索又從V1

到V3,再繼續(xù)進(jìn)行下去由此,得到的頂點(diǎn)訪問(wèn)序列為:

2012年7月21日28

2、圖的深度優(yōu)先遍歷算法;

-在遍歷過(guò)程中必須能夠區(qū)分頂點(diǎn)是否已被訪問(wèn)「因此需附設(shè)一

訪問(wèn)標(biāo)志數(shù)組flag[N],用flag[O]..flag[N-l]來(lái)標(biāo)示相應(yīng)的頂點(diǎn)是否

訪問(wèn)過(guò),其初值為0,一旦某個(gè)頂點(diǎn)被訪問(wèn),則其相應(yīng)的分量置

為1。

(1)形式算法

【算法6-4]圖的深度優(yōu)先遍歷

intflag[N]={0};/*N為圖的頂點(diǎn)個(gè)數(shù)*/

voidDFSTraverse(Graph*G,intv)

{Visited(v);flag[v]=1;/*訪問(wèn)頂點(diǎn)v,并置訪問(wèn)標(biāo)記*/

for(w=FisrAdjVex(G,v);w;w=NextAdjVex(G,v,w))

if(!flag[w])

DFSTraverse(G,w);

)

(2)以鄰接表為存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)圖的深度優(yōu)先遍歷顯

【算法6?5】深度優(yōu)先遍歷鄰接表存儲(chǔ)的圖

intflag[N]={0};/*全局?jǐn)?shù)組初始化為0*/

voidDFS(VertexNodeAdjList[],inti)

{/*以頂點(diǎn)[為出發(fā)點(diǎn),對(duì)鄰接表存儲(chǔ)的圖G進(jìn)行DFS搜索*/

EdgeNode*p;

Visited(AdjList[i].vertex);/*訪問(wèn)頂點(diǎn)vi*/

flag[i]=1;/*標(biāo)記頂點(diǎn)i已訪問(wèn)*/

p=AdjList[i].firstedge;/*取頂點(diǎn)i鄰接邊鏈表的頭指針*/

while(p)

{j=p->adjvex;/*依次搜索頂點(diǎn)i的鄰接點(diǎn)頂點(diǎn)j*/

if(!flag[jj)/*若頂點(diǎn)j尚未訪問(wèn),則以頂點(diǎn)j為出發(fā)點(diǎn)深度搜索*/

DFS(AdjList,j);

p=p->next;/*找頂點(diǎn)i的下一個(gè)鄰接點(diǎn)*/

}

)

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義30

voidDFSTraverseAL(VertexNodeAdjList[])

inti;

for(i=0;i<N;i++)

if(!flag[i])

DFS(AdjList,i);

3、算法分析

如果圖是連通的,函數(shù)DFS只需被外界函數(shù)調(diào)用一次,

圖中的各個(gè)頂點(diǎn)就全部得到訪問(wèn)。如果圖是非連通的,函

數(shù)DFS被外界函數(shù)調(diào)用一次僅訪問(wèn)了包括出發(fā)點(diǎn)的連通分量

,要想訪問(wèn)其它連通分量,必須找另一個(gè)連通分量上的頂

點(diǎn)作出發(fā)點(diǎn),有幾個(gè)連通分量就要調(diào)用幾次DFS才能訪問(wèn)全

圖,因此需要函數(shù)DFSTraverseAL。雖然對(duì)DFS的調(diào)用出現(xiàn)

在循環(huán)中,對(duì)每個(gè)頂點(diǎn)都可以調(diào)用一次DFS函數(shù),但一旦某

個(gè)頂點(diǎn)被標(biāo)志成已訪問(wèn)標(biāo)志,就不再?gòu)乃霭l(fā)進(jìn)行搜索,

所以實(shí)質(zhì)上是圖中有幾個(gè)連通分量,通過(guò)DFSTraverseAL就

會(huì)幾次調(diào)用DFS函數(shù)。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義32

在遍歷時(shí),對(duì)圖中每個(gè)頂點(diǎn)至多調(diào)用一次DFS函數(shù),因?yàn)?/p>

一旦某個(gè)頂點(diǎn)被標(biāo)志成已被訪問(wèn),就不再?gòu)乃霭l(fā)進(jìn)行搜索。

因此,遍歷圖的過(guò)程實(shí)質(zhì)上是對(duì)每個(gè)頂點(diǎn)查找其鄰接點(diǎn)的過(guò)程

o其耗費(fèi)的時(shí)間則取決于所采用的存儲(chǔ)結(jié)構(gòu)。當(dāng)用二維數(shù)組表

示鄰接矩陣圖的存儲(chǔ)結(jié)構(gòu)時(shí),查找每個(gè)頂點(diǎn)的鄰接點(diǎn)所需時(shí)間

為og2),其中n為圖中頂點(diǎn)數(shù)。而當(dāng)以鄰接表作圖的存儲(chǔ)結(jié)構(gòu)時(shí)

,找鄰接點(diǎn)所需時(shí)間為。⑥,其中e為無(wú)向圖中邊的數(shù)或有向圖

中弧的數(shù)。由此,當(dāng)以鄰接表作存儲(chǔ)結(jié)構(gòu)時(shí),深度優(yōu)先搜索遍

歷圖的時(shí)間復(fù)雜度為O(n+e)o

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義33

52廣度優(yōu)法搜索

廣度優(yōu)先搜索(Brcadth_FirstSearch)遍歷類似于樹(shù)的按層次

遍歷的過(guò)程。

1、廣度優(yōu)先搜索的概念

假設(shè)從圖中某頂點(diǎn)v出發(fā),在訪問(wèn)了v之后依次訪問(wèn)v的各個(gè)未

曾訪問(wèn)過(guò)和鄰接點(diǎn),然后分別從這些鄰接點(diǎn)出發(fā)依次訪問(wèn)它們的

鄰接點(diǎn),并使“先被訪問(wèn)的頂點(diǎn)的鄰接點(diǎn)”先于“后被訪問(wèn)的頂

點(diǎn)的鄰接點(diǎn)”被訪問(wèn),直至圖中所有已被訪問(wèn)的頂點(diǎn)的鄰接點(diǎn)都

被訪問(wèn)到。若此時(shí)圖中尚有頂點(diǎn)未被訪問(wèn),則另選圖中一個(gè)未曾

被訪問(wèn)的頂點(diǎn)作起始點(diǎn),重復(fù)上述過(guò)程,直至圖中所有頂點(diǎn)都被

訪問(wèn)到為止。換句話說(shuō),廣度優(yōu)先搜索遍歷圖的過(guò)程中以v為起

始點(diǎn),由近至遠(yuǎn),依次訪問(wèn)和v有路徑相通且路徑長(zhǎng)度為1,2,…的

頂點(diǎn)。34

例如,對(duì)下圖所示無(wú)向圖G5進(jìn)行廣度優(yōu)先搜索遍歷,首先

訪問(wèn)V1和V1的鄰接點(diǎn)V2和丫3,然后依次訪問(wèn)V2的鄰接點(diǎn)V4和V5及

V3的鄰接點(diǎn)V6和V7,最后訪問(wèn)的鄰接點(diǎn)Vg。由于這些頂點(diǎn)的鄰

接點(diǎn)均已被訪問(wèn),并且圖中所有頂點(diǎn)都被訪問(wèn),由些完成了圖

的遍歷。得到的頂點(diǎn)訪問(wèn)序列為:

2012年7月21日姒站笫惚護(hù)乂35

2、圖的廣度優(yōu)先遍歷算法

和深度優(yōu)先搜索類似,在遍歷的過(guò)程中也需要一個(gè)訪問(wèn)標(biāo)志

數(shù)組。并且,為了順次訪問(wèn)路徑長(zhǎng)度為2、3、…的頂點(diǎn),需附設(shè)

隊(duì)列以存儲(chǔ)已被訪問(wèn)的路徑長(zhǎng)度為1、2、…的頂點(diǎn)。

【算法6-6】圖的廣度優(yōu)先遍歷

intflag[N]={0};/*全局?jǐn)?shù)組初始化為0*/

voidBFSTraverse(Graph*G,intv)

{/*對(duì)G進(jìn)行廣度優(yōu)先遍歷*/

InitQueue(Q);/*置空的隊(duì)列Q*/

if(!flag[v])/*v尚未訪問(wèn)*/

{EnQueue(Q,v);/*v入隊(duì)*/

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義36

3

while(IQueueEmpty(Q))/*隊(duì)列不空*/

{DeQueue(Q,u);/*隊(duì)頭元素出隊(duì)*/

Visited(u);/*訪問(wèn)該頂點(diǎn)*/

flag[u]=l;/*置訪問(wèn)標(biāo)志*/

for(w=FirstAdjVex(G,u);w;w=NextAdjVex(G,u,w))

if(!flag[w])/*依次將尚未訪問(wèn)的鄰接頂點(diǎn)*/

EnQueue(Q,w);

(2)以鄰接矩陣為存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)廣度優(yōu)先遍歷

【算法6?7】廣度優(yōu)先遍歷鄰接矩陣存儲(chǔ)的圖

intflag[N]={0};/*全局?jǐn)?shù)組初始化為0*/

voidBFS(MGraph*G,inti)

{/*以頂點(diǎn)i為出發(fā)點(diǎn),對(duì)鄰接矩陣存儲(chǔ)的圖G進(jìn)行BFS搜索*/

■ntj;

intQ[N],front,rear;/*定義隊(duì)列空間和隊(duì)頭隊(duì)尾變量*/

front=0;rear=-1;/*初始化為空,

Visited(G->vexs[i]);/*訪問(wèn)頂點(diǎn)產(chǎn)/

flag[i]=1;/*置訪問(wèn)標(biāo)志*/

rear++;Q[rear]=i;/*出發(fā)點(diǎn)頂點(diǎn)i入隊(duì),

while(front<=rear)/*當(dāng)隊(duì)不空*/

{i=Q[rear];front++;/*出隊(duì)*/

for0=0;j<N;j++)/*依次搜索頂點(diǎn)[的鄰接點(diǎn)*/

if(G->edges[i][j]==1&&!flag[jj)/*若鄰接點(diǎn)頂點(diǎn)j未訪問(wèn),

{Visited(G->vexs[j]);/*訪問(wèn)頂點(diǎn)j*/

flag[j]=1;/*置訪問(wèn)標(biāo)志*/

rear++;Q[rear]=j;/*訪問(wèn)過(guò)的頂點(diǎn)j入隊(duì)*/

voidBFSTraverseAL(Mgraph*G)

inti;

for(i=0;i<N;i++)

if(!flag[i])BFS(G,i);

3、算法分析

同樣,對(duì)于一個(gè)連通圖一次調(diào)用BFS就能訪問(wèn)所有的頂點(diǎn),

對(duì)于非連通圖只能遍歷包括出發(fā)點(diǎn)的連通分量,如遍歷其它的

連通分量,需再選擇其它連通分量上的頂點(diǎn)做出發(fā)點(diǎn)。

分析上述算法可知,每個(gè)頂點(diǎn)至多進(jìn)一次隊(duì)列。遍歷圖的

過(guò)程實(shí)質(zhì)是通過(guò)邊或弧找鄰接點(diǎn)的過(guò)程,因此廣度優(yōu)先搜索遍

歷圖的時(shí)間復(fù)雜度和深度優(yōu)先搜索遍歷相同,兩者不同之處僅

僅在于對(duì)頂點(diǎn)訪問(wèn)的順序不同。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義40

M3應(yīng)用囹的遍歷囹判斷囹的接通但

1.無(wú)向圖的連通性

在對(duì)無(wú)向圖進(jìn)行遍歷時(shí),對(duì)于連通圖,僅需從圖中任一頂點(diǎn)

出發(fā),進(jìn)行深度優(yōu)先搜索或廣度優(yōu)先搜索,便可訪問(wèn)到圖中所

有頂點(diǎn)。對(duì)非連通圖,則需從多個(gè)頂點(diǎn)出發(fā)進(jìn)行搜索,而每一

次從一個(gè)新的起始點(diǎn)出發(fā)進(jìn)行搜索過(guò)程中得到的頂點(diǎn)訪問(wèn)序列

恰為其各個(gè)連通分量中的頂點(diǎn)集。

非連通圖G3:按照G3的鄰接表進(jìn)行深度優(yōu)先搜索遍歷,需由

算法調(diào)用兩次DFS(即分別從頂點(diǎn)A和D出發(fā)),得到的頂點(diǎn)訪

問(wèn)序列分別為:

ABFEDC

這兩個(gè)頂點(diǎn)集分別加上所有依附于這些頂點(diǎn)的邊,便構(gòu)

成了非連通圖G3的兩個(gè)連通分量。41

序號(hào)

A

014A

1B05A

2C3A

D

32A

4E

05A

F

514A

(a)無(wú)向圖G3

G3的球表

因此,要想判定一個(gè)無(wú)向圖是否

為連通圖,或有幾個(gè)連通分量,就可

設(shè)一個(gè)計(jì)數(shù)變量count,初始時(shí)取值為0,

在算法6-5的第二個(gè)for循環(huán)中,每調(diào)用

一次DFS,就給count增1。這樣,當(dāng)整

(b)G3的兩徜1通分量

個(gè)算法結(jié)束時(shí),依據(jù)count的值,就可

確定圖的連通性了。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義42

2.有向圖的連通性

有向圖的連通性不同于無(wú)向圖的連通性,可分為弱連通、

單側(cè)連通和強(qiáng)連通。對(duì)有向圖的強(qiáng)連通性以及強(qiáng)連通分量的判

定,可通過(guò)對(duì)以十字鏈表為存儲(chǔ)結(jié)構(gòu)的有向圖的深度優(yōu)先搜索

實(shí)現(xiàn)。

由于強(qiáng)連通分量中的結(jié)點(diǎn)相互可達(dá),故可先按出度深度優(yōu)

先搜索,記錄下訪問(wèn)結(jié)點(diǎn)的順序和連通子集的劃分,再按入度

深度優(yōu)先搜索,對(duì)前一步的結(jié)果再劃分,最終得到各強(qiáng)連通分

量。若所有結(jié)點(diǎn)在同一個(gè)強(qiáng)連通分量中,則該圖為強(qiáng)連通圖。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義43

4、女感樹(shù)我景小皮戚樹(shù)

41景小女感樹(shù)

1、最小生成樹(shù)的概念

由生成樹(shù)的定義可知,無(wú)向連通圖的生成樹(shù)不是唯一的。連

通圖的一次遍歷所經(jīng)過(guò)的邊的集合及圖中所有頂點(diǎn)的集合就構(gòu)

成了該圖的一棵生成樹(shù),對(duì)連通圖的不同遍歷,如遍歷出發(fā)點(diǎn)

不同或存儲(chǔ)點(diǎn)的順序不同,就可能得到不同的生成樹(shù)。下圖(a)

、(b)和?所示的均為無(wú)向連通圖G5的生成樹(shù)。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義44

⑴對(duì)于有n個(gè)頂點(diǎn)的無(wú)向連通圖,無(wú)論其生成樹(shù)的形態(tài)如何

,所有生成樹(shù)中都有且僅有n—1條邊。

⑵如果無(wú)向連通圖是一個(gè)網(wǎng),那么,它的所有生成樹(shù)中必

有一棵邊的權(quán)值總和最小的生成樹(shù),我們稱這棵生成樹(shù)為最小

生成樹(shù),簡(jiǎn)稱為最小生成樹(shù)。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義45

2、如何找到一個(gè)連通網(wǎng)絡(luò)的最小生成樹(shù)?5

(1)MST,性質(zhì):

MST性質(zhì):設(shè)G=(Vn,En)是一個(gè)連通網(wǎng)絡(luò),U是頂點(diǎn)集Vn

的一個(gè)真子集。若⑴,v)是G中所有的一個(gè)端點(diǎn)在U(即uCU)

而另一個(gè)端點(diǎn)不在U(即vGVn—U)里的邊中,具有最小權(quán)值

的一條邊,則一定存在的一棵最小生成樹(shù)包括此邊

G(u,v)o

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義46

MST性質(zhì)的用反證法證明:---—一

即首先假設(shè)G的任何一棵最小生成樹(shù)中都不含此邊(u,v),

設(shè)T是G的一棵最小生成樹(shù),但不包含邊(u,v)。由于T是樹(shù)且是

連通的,因此有一條從u到v的路徑;且該路徑上必有一條連接

兩頂點(diǎn)集U和Vn—U的邊(u',v'),其中u'WU,v'€Vn-U

,否則u和v不連通。當(dāng)把邊(u,v)加入樹(shù)T時(shí),得到一^個(gè)含有邊

(U,V)的回路。若刪去邊(U‘,V’),則上述回路即被消除,由此

得到另一棵生成樹(shù)T',T’和T的區(qū)別僅在于用邊(u,V)取代了

T中的邊(u‘,v’)。因?yàn)?u,v)的權(quán)W(u',v')的權(quán),故T'的

權(quán)WT的權(quán),因此T'也是G的最小生成樹(shù),它包含邊(u,v),與

假設(shè)矛盾。MST性質(zhì)得以證明。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義47

42構(gòu)造景小金鼠樹(shù)的儂勿喜法

1、Prim算法

設(shè)G=(Vn,E,為一網(wǎng)圖,其中V。為網(wǎng)圖中所有頂點(diǎn)的集合

,En為網(wǎng)圖中所有帶權(quán)邊的集合。

設(shè)置兩個(gè)新的集合U和T,其中集合U用于存放G的最小生

成樹(shù)中的頂點(diǎn),集合T存放G的最小生成樹(shù)中的邊。令集合U的

初值為U={u。}(設(shè)從頂點(diǎn)u0出發(fā)構(gòu)造最小生成樹(shù)),集合T的

初值為T={}。Prim算法的思想是,從所有uWU,vGV”一U的

邊中,選取具有最小權(quán)值的邊(u,v),將頂點(diǎn)v加入集合U中,將

邊(u,V)加入集合T中,如此不斷重復(fù),直到U=Vn時(shí),最小生成

樹(shù)構(gòu)造完畢,這時(shí)集合T中包含了最小生成樹(shù)的所有邊。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義48

Prim算法可用下述過(guò)程描述,其中用W.表示頂點(diǎn)u與頂點(diǎn)v

邊上的權(quán)值。

(l)U={u0}?T={};

(2)while(U^VJdo

.(u,v)=min{wuv|u€U,v€Vn-U)

T=T+{(u,v)}

U=U+{v}

⑶結(jié)束。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義49

2、Prim過(guò)程

下圖(a)所示的一個(gè)網(wǎng)圖,按照Prim方法,從頂點(diǎn)1出發(fā),該網(wǎng)

的最小生成樹(shù)的產(chǎn)生過(guò)程如圖(b)、(c)、(d)、⑹、⑴和(g)所示。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義50

3、Prim算法實(shí)現(xiàn):

這里設(shè)置三個(gè)輔助向量cost[N]、tree[N]>flag[N]:

其中cost用來(lái)保存屬于集合U中的頂點(diǎn)連通不屬于集合U中

的每一頂點(diǎn)的邊中具有最小值邊的權(quán)值,cost的最終值是最小生

成樹(shù)中每條邊的權(quán)值;

數(shù)組tree對(duì)應(yīng)cost,用來(lái)保存依附于該邊的在集合U中的頂點(diǎn)

,如tree[4]=l,說(shuō)明當(dāng)前這條邊是(1,4),即用頂點(diǎn)1連通的頂點(diǎn)4

,其權(quán)值保存在cost[4]中;flag仍為標(biāo)志數(shù)組,用來(lái)標(biāo)明某一點(diǎn)

是否進(jìn)入了U。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義51

表6-1給出了用上述算法構(gòu)造網(wǎng)圖6-22⑷的最小生成樹(shù)的過(guò)

程中,數(shù)組tree、cost以及集合U的變化情況,

表6」用Prim算法構(gòu)造最小生成樹(shù)過(guò)程中各參數(shù)的變化示意

Q)

(2)⑶(4)(6)(7)

頂點(diǎn)(初始狀態(tài))

costtreecosttreecosttreecosttreecosttreecosttreecosttree

000000000000000

1500國(guó)o國(guó)o國(guó)o國(guó)0國(guó)0回o

2600600600523523456網(wǎng)6

38(J651504國(guó)4國(guó)4國(guó)404

01£11

480401畫1圓1圓1

8Q8(J

570430303回3國(guó)3

03

68(J8(J80423423畫3

{0}{0,1}{0J,4}{0,1,4,3){0,143,5}{0"{0,1,43

U

3,5,6}5,6,2}

(){(0,1)}{(0」),?1),(1⑼{。1),(L4),{(0,1),(1,4),?1),。,4),

T。倒(43}(4,3)3)}(4,3),(3,5),(4,3),(3,5),

0,6)}(3,6),(6,2))

【算法6-9]用Prim算法構(gòu)造無(wú)向連通網(wǎng)的最小生成樹(shù)

#defineMAXCOSTj■/*定義MAXCOST為一個(gè)足夠大的常量值*/

voidPrim(intgm[N][N],inttree[N],intcost[N])

{/*從序號(hào)為。的頂點(diǎn)出發(fā),建立最小生成樹(shù),9m[N][N]是其鄰接矩陣*/

/*建立的最小生成樹(shù)存于數(shù)組tree中,對(duì)應(yīng)的邊值在cost中*/

intflag[N]={0};

inti,j,k,mincost;

for(i=O;i<N;i++)

/*從存儲(chǔ)序號(hào)為。的頂點(diǎn)出發(fā)生成最小生成樹(shù)*/

tree[i]=O;

}

flag[0]=1;

for(i=1;i<N;i++)/*N一次循環(huán),尋找當(dāng)前最小權(quán)值的邊,

{mincost=MAXCOST;

fora=1;j<N;j++)

{if(flag[j]==0&&cost[j]<mincost)

{mincost=cost[j];

k=j;

/*記憶最小的邊*/

flag[k]=l;

for(j=l;j<N;j++)

if(gm[k][j]<cost[j])

{cost[j]=gm[k][j];

tree[j]=k;

4、時(shí)間性能

在Prim算法中,第一個(gè)for循環(huán)的執(zhí)行次數(shù)為n—1,第二個(gè)

for循環(huán)中又包括了一個(gè)while循環(huán)和一個(gè)for循環(huán),執(zhí)行次數(shù)為

2(n-l)2,所以Prim算法的時(shí)間復(fù)雜度為:O(n2)

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義55

44構(gòu)造景小金鼠樹(shù)的加等讓

Kruskal算法是一種按照網(wǎng)中邊的權(quán)值遞增的順序構(gòu)造最小生成

樹(shù)的方法。

1、Kruskal算法基本思想

設(shè)無(wú)向連通網(wǎng)為G=(Vn,En),令G的最小生成樹(shù)為T=(V『ET)

,其初態(tài)為:V=V即開(kāi)始時(shí)頂點(diǎn)集T為V0,邊集T

Tn,ET={},E

為空,此時(shí)T中沒(méi)有邊,即各頂點(diǎn)各自構(gòu)成一個(gè)連通子圖。然后

從沒(méi)有進(jìn)入ET的邊集(E「-ET)中不斷選取權(quán)值最小的邊,若該

邊的兩個(gè)頂點(diǎn)屬于T的兩個(gè)不同的連通子圖,加入該邊不構(gòu)成回

路,則將此邊作為最小生成樹(shù)的邊加入到ET中;若該邊的加入

造成回路,則舍去此邊,則選取下一條權(quán)值較小的邊,如此下

去,選取n-l次后,此時(shí)ET中必有n-l條邊,n-l條邊連通了n個(gè)頂

點(diǎn),連通子圖的個(gè)數(shù)為1,此連通子圖便為G的一棵最小生成樹(shù)

O

2、Kruskal方法過(guò)程

對(duì)于下圖所示的網(wǎng),按照Kruskal方法構(gòu)造最小生成樹(shù)的過(guò)程

如下圖所示。在構(gòu)造過(guò)程中,按照網(wǎng)中邊的權(quán)值由小到大的順

序,不斷選取當(dāng)前未被選取的邊集中權(quán)值最小的邊。依據(jù)生成

樹(shù)的概念,n個(gè)結(jié)點(diǎn)的生成樹(shù),有n—1條邊,故反復(fù)上述過(guò)程,

直到選取了n—1條邊為止,就構(gòu)成了一棵最小生成樹(shù)。

3、Kruskal算法的實(shí)現(xiàn)

⑴相關(guān)的數(shù)據(jù)結(jié)構(gòu),邊的表示如下:

typedefstruct

{intVp

;是兩個(gè)頂點(diǎn)的序號(hào)*/

intv2/*vPV2

intcost;/*邊的權(quán)值*/

}EdgeType;

EdgeTypeedges[E],T[N-1];

向量edges存儲(chǔ)網(wǎng)中所有的邊,每個(gè)分量cdges[i]代表網(wǎng)中的一

條邊,其中edges[i].V[和edges[i]凡表示該邊的兩個(gè)頂點(diǎn)的序號(hào)

(0..N-1),edgcs[i].cost表示這條邊的權(quán)值;最終最小生成樹(shù)的邊

存放在

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義58

在結(jié)構(gòu)數(shù)組edges中,每個(gè)分量edges[i]代表網(wǎng)中的一條邊,

其中edges[i].v[和edges[I]上表示該邊的兩個(gè)頂點(diǎn),edges[i].cost表

示這條邊的權(quán)值。為了方便選取當(dāng)前權(quán)值最小的邊,事先把

數(shù)組edges中的各元素按照其cost域值由小到大的順序排列。

edges數(shù)組狀態(tài)如下:

/p>

v25466143235

cost30404245505052606570

數(shù)據(jù)結(jié)構(gòu)講義

2012年7月21日59

father數(shù)組,因?yàn)榭偸且_定兩個(gè)頂點(diǎn)是否屬于同一個(gè)集合(

一個(gè)連通子圖中包含的頂點(diǎn)認(rèn)為是一個(gè)集合),因此設(shè)計(jì)一個(gè)

數(shù)組:

intfather[N];

利用father]],可以通過(guò)回溯的方法最終確定頂點(diǎn)i所在的集

合(找到集合的根結(jié)點(diǎn),集合的表示及合并采用5.9.2節(jié)所介紹的

方法)。

初值:表示各個(gè)頂點(diǎn)在不同的集

father[i]=-l(i=O,l/--,N-l),

合上。

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義60

依次取出edges數(shù)組中沒(méi)有選入T中的最小邊的兩個(gè)頂點(diǎn),查

找它們所屬的集合,若不在一^個(gè)集合中就選中這條邊,即把這

條邊加入到T中,因此連通了兩個(gè)集合。

兩個(gè)變量:intvfi,vf2;存儲(chǔ)兩頂點(diǎn)所在集合的根結(jié)點(diǎn)若不

等于vf2,表明這條邊的兩個(gè)頂點(diǎn)不屬于同一集合,則將這條邊

作為最小生成樹(shù)的邊選入到T中,并合并它們所屬的兩個(gè)集合。

father數(shù)組的變化情況如表6-2所示。

father[]0123456加入的邊對(duì)應(yīng)的頂點(diǎn)集合

-1■4-4-4-■4-4-1

-1-1-1-1-13-1(3,5)(3,5)

-1-1-1-113-1(1,4)(3,5),(1,4)

-1-1-1-1133(3,6)(3,5,6),(1,4)

-1-1-12133(2,6)(3,5,6,2),(1,4)

-10-12133(0,1)(3,5,6,2),(1,4,0)

20-12133(3,4)(3,5,6,2,1,4,0)

(3)算法實(shí)現(xiàn)____

[算法0]Kruskal方法構(gòu)造無(wú)向網(wǎng)的最小生成樹(shù)

voidKruskal(EdgeTypeedges[],EdgeTypeT[])

{/*用Kruskal方法構(gòu)造圖的最小生成樹(shù)*/

中是圖中各條邊,且已按其權(quán)值從小到大有序,最小生成樹(shù)的邊在T中,

intfather[N];

inti,j,vf1,vf2;

for(i=O;i<N;i++)father[i]=-1;

i=O;j=O;

while(i<E&&j<N-1)

{vf1=Find(father,edges[i].v1);

vf2=Find(father,edges[i].v2);

if(vf1!=vf2)

{father[vf2]=vf1;

T[j]=edges[i];

j++;

■++;

2012年7月21日數(shù)據(jù)結(jié)構(gòu)講義62

intFind(intfather口,intv)

intt;

t=v;

while(father[t]>=0)

t=fatherft];

return(t);

___________________一一一―――14

在Kruskal算法中,while循環(huán)是影響時(shí)間效率的主要操作,其

循環(huán)次數(shù)最多為e次,其內(nèi)部調(diào)用的Find函數(shù)的內(nèi)部循環(huán)次數(shù)最

多為n次,所以Kruskal算

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論