數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告--最小生成樹(shù)_第1頁(yè)
已閱讀1頁(yè),還剩21頁(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)介

1、<p>  數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告</p><p><b>  院系:計(jì)算機(jī)學(xué)院</b></p><p><b>  班級(jí):軟件121班</b></p><p><b>  姓名: </b></p><p><b>  學(xué)號(hào): </b></p

2、><p><b>  題目:最小生成樹(shù)</b></p><p><b>  指導(dǎo)老師: </b></p><p><b>  一、引言3</b></p><p><b>  二、設(shè)計(jì)題目3</b></p><p><b>

3、  1.問(wèn)題描述3</b></p><p><b>  2.系統(tǒng)要求3</b></p><p><b>  3.測(cè)試數(shù)據(jù)4</b></p><p><b>  4.實(shí)現(xiàn)提示4</b></p><p><b>  5.參考文獻(xiàn)4</b>

4、</p><p><b>  6.運(yùn)行環(huán)境5</b></p><p><b>  三、需求分析5</b></p><p>  1.如何選擇存儲(chǔ)結(jié)構(gòu)去建立一個(gè)帶權(quán)網(wǎng)絡(luò)。5</p><p>  2.如何在所選存儲(chǔ)結(jié)構(gòu)下輸出這個(gè)帶權(quán)網(wǎng)絡(luò)。5</p><p>  3.如何實(shí)現(xiàn)

5、PRIM算法和Kruskal算法的功能。5</p><p>  4.如何從每個(gè)頂點(diǎn)開(kāi)始找到所有的最小生成樹(shù)的頂點(diǎn)。6</p><p>  5.如何輸出最小生成樹(shù)的邊及其權(quán)值。6</p><p><b>  四、概要設(shè)計(jì)6</b></p><p>  2.圖的存儲(chǔ)結(jié)構(gòu)7</p><p>&

6、lt;b>  3.流程圖7</b></p><p><b>  五、詳細(xì)設(shè)計(jì)8</b></p><p><b>  1.主函數(shù)模塊8</b></p><p>  2.對(duì)路徑權(quán)值進(jìn)行排序9</p><p>  六、調(diào)試與分析13</p><p>&l

7、t;b>  七、測(cè)試結(jié)果16</b></p><p>  八、設(shè)計(jì)心得體會(huì)16</p><p>  附錄(源代碼)17</p><p><b>  摘要</b></p><p>  最小生成樹(shù)是數(shù)據(jù)結(jié)構(gòu)中圖的一種重要應(yīng)用,在圖中對(duì)于n個(gè)頂點(diǎn)的連通網(wǎng)可以建立許多不同的生成樹(shù),最小生成樹(shù)就是在所有生成

8、樹(shù)中總的代價(jià)最小的生成樹(shù)。本課程設(shè)計(jì)是以鄰接矩陣作為圖的存儲(chǔ)結(jié)構(gòu),分別采用Prim和Kruskal算法求最小生成樹(shù)。Kruskal算法和Prim算法是求最小生成樹(shù)的常用算法它們分別適用于稠密圖和稀疏圖。最小生成樹(shù)的應(yīng)用非常的廣,如礦井通風(fēng)設(shè)計(jì)和改造最優(yōu)化方面以及如何搭建最短的網(wǎng)絡(luò)線纜, 構(gòu)建造價(jià)最低的通訊網(wǎng)絡(luò) 。</p><p><b>  一、引言</b></p&

9、gt;<p>  本課程設(shè)計(jì)我們要解決的問(wèn)題是圖最小生成樹(shù)問(wèn)題。要用到圖的先相關(guān)數(shù)據(jù)結(jié)構(gòu)和求最小生成樹(shù)的兩種數(shù)據(jù)結(jié)構(gòu)算法普里姆算法和克魯斯卡爾算法,以及儲(chǔ)存圖的邊和點(diǎn)的鄰接矩陣。 </p><p>  本課程設(shè)計(jì)要解決的問(wèn)題構(gòu)造連通網(wǎng)的最小生成樹(shù) ,我們首先要做的是創(chuàng)建一個(gè)鄰接矩陣,用以來(lái)存儲(chǔ)圖,然后我們要想好怎樣利用普里姆算法和克魯斯卡爾算法來(lái)構(gòu)造最小生成樹(shù)。把這兩種算法寫(xiě)入主

10、函數(shù),調(diào)試好程序。最后寫(xiě)好報(bào)告。</p><p><b>  二、設(shè)計(jì)題目</b></p><p><b>  1.問(wèn)題描述</b></p><p>  若要在n個(gè)城市之間建設(shè)通信網(wǎng)絡(luò),只需要假設(shè)n-1條線路即可。如何以最低的經(jīng)濟(jì)代價(jià)建設(shè)這個(gè)通信網(wǎng),是一個(gè)網(wǎng)的最小生成樹(shù)問(wèn)題。</p><p><

11、;b>  2.系統(tǒng)要求</b></p><p>  利用克魯斯卡爾算法求網(wǎng)的最小生成樹(shù)。</p><p>  利用普里姆算法求網(wǎng)的最小生成樹(shù)。</p><p>  要求輸出各條邊及它們的權(quán)值。</p><p><b>  3.測(cè)試數(shù)據(jù)</b></p><p><b> 

12、 4.實(shí)現(xiàn)提示</b></p><p>  通信線路一旦建成,必然是雙向的。因此,構(gòu)造最小生成樹(shù)的網(wǎng)一定是無(wú)向圖。設(shè)圖的頂點(diǎn)數(shù)不超過(guò)30個(gè),并為簡(jiǎn)單起見(jiàn),網(wǎng)中邊的權(quán)值設(shè)成小于100的整數(shù),100則表示沒(méi)有路徑。</p><p><b>  5.參考文獻(xiàn)</b></p><p>  [1]  嚴(yán)蔚敏. 數(shù)

13、據(jù)結(jié)構(gòu)(C語(yǔ)言版)[M]. 北京:清華大學(xué)出版社,1997. </p><p>  [2]  譚浩強(qiáng). C程序設(shè)計(jì)(第三版)[M]. 北京:清華大學(xué)出版社,2005.1.</p><p>  [3]  二霍紅衛(wèi)算法設(shè)計(jì)與分析〔」西安西安電子科技大學(xué)出版社,2005.113-127. </p>

14、;<p>  [4]  陳杰.計(jì)算機(jī)專(zhuān)業(yè)課程設(shè)計(jì)中的需求分析[J].集美大學(xué)學(xué)報(bào),2009,10(2):89—92. </p><p>  [5]  高一凡. 數(shù)據(jù)結(jié)構(gòu)算法實(shí)現(xiàn)及解析[M ]. 西安:西安電子科技大學(xué)出版社, 2002 </p><p><b>  6

15、.運(yùn)行環(huán)境</b></p><p><b>  VC++6.0</b></p><p><b>  三、需求分析 </b></p><p>  1.如何選擇存儲(chǔ)結(jié)構(gòu)去建立一個(gè)帶權(quán)網(wǎng)絡(luò)。 </p><p>  此問(wèn)題的關(guān)鍵在于如何實(shí)現(xiàn)PRIM算法和Kruskal算法,實(shí)

16、現(xiàn)的過(guò)程中如何得到構(gòu)成最小生成樹(shù)的所有頂點(diǎn),此外輸出也是一個(gè)關(guān)鍵問(wèn)題所在,在此過(guò)程中經(jīng)過(guò)了多次調(diào)試。</p><p>  2.如何在所選存儲(chǔ)結(jié)構(gòu)下輸出這個(gè)帶權(quán)網(wǎng)絡(luò)。</p><p>  將圖中的所有頂點(diǎn)存儲(chǔ)到一個(gè)一維數(shù)組中,通過(guò)一個(gè)二維數(shù)組用鄰接矩陣連實(shí)現(xiàn)對(duì)各邊權(quán)值的存儲(chǔ)</p><p>  3.如何實(shí)現(xiàn)PRIM算法和Kruskal算法的功能。</p>

17、<p>  首先我們對(duì)prim算法的問(wèn)題進(jìn)行大致的概要分析:</p><p>  假設(shè)N=(V,{E})是連通網(wǎng),TE是N上最小生成樹(shù)中邊的集合。算法從U={u0}(u0∈V),TE={}開(kāi)始,重復(fù)執(zhí)行下述操作:在所有u∈U,v∈V-U的邊(u,v)∈E中找一條代價(jià)最小的邊(u0,v0)并入集合TE,同時(shí)v0并入U(xiǎn),直至U=V為止。此時(shí)TE中必有n-1條邊,則T=(V,{TE})為N的最小生成樹(shù)。&l

18、t;/p><p>  克魯斯卡爾算法從另一種途徑求網(wǎng)的最小生成樹(shù):</p><p>  假設(shè)連通網(wǎng)N=(V,{E}),則另最小生成樹(shù)的初始狀態(tài)為只有n個(gè)頂點(diǎn)而無(wú)邊的非連通圖T=(V,{}),圖中每個(gè)頂點(diǎn)自成一個(gè)連通分量。在E中選擇代價(jià)最小的邊若該邊依附的頂點(diǎn)落在T中不同的連通分量上,則將此邊加入到T中,否則舍去此邊而選擇下一條代價(jià)最小的邊。以此類(lèi)推直至T中的所有頂點(diǎn)都在同一連通分量上為止。&l

19、t;/p><p>  4.如何從每個(gè)頂點(diǎn)開(kāi)始找到所有的最小生成樹(shù)的頂點(diǎn)。</p><p>  對(duì)于prim算法從圖的點(diǎn)集中任取一個(gè)頂點(diǎn)作為起始頂點(diǎn),然后找到依附于該頂點(diǎn)的所有邊選取權(quán)值最小的,依次找下去直至圖中所有頂點(diǎn)都在一個(gè)點(diǎn)集中為止。對(duì)于克魯斯卡爾算法則通過(guò)對(duì)權(quán)值進(jìn)行排序找出權(quán)值最小的頂點(diǎn)和邊并把該邊的頂點(diǎn)并入點(diǎn)集之中。</p><p>  5.如何輸出最小生成樹(shù)的

20、邊及其權(quán)值。</p><p>  通過(guò)訪問(wèn)數(shù)組來(lái)實(shí)現(xiàn)對(duì)最小生成樹(shù)邊和權(quán)值的輸出。</p><p><b>  四、概要設(shè)計(jì)</b></p><p>  1、設(shè)定圖的抽象數(shù)據(jù)類(lèi)型: ADT Graph{ </p><p>  數(shù)據(jù)對(duì)象V:V是具有相同特性的數(shù)據(jù)元素的集合,稱(chēng)為點(diǎn)集. 

21、數(shù)據(jù)關(guān)系R: R={VR} </p><p>  VR={(v,w)|v,w屬于V,(v,w)表示v和w之間存在的路徑} </p><p><b>  基本操作P: </b></p><p>  CreatGraph(&G,V,VR) </p><p>  初始條

22、件:V是圖的頂點(diǎn)集,VR是圖中弧的集合. 操作結(jié)果:按V和VR是定義構(gòu)造圖G. </p><p>  Sort(edge* ,MGraph *) </p><p>  初始條件: 圖G存在,各邊權(quán)值已知; 操作結(jié)果:對(duì)權(quán)值進(jìn)行排序; </p><p>  Find(int *,

23、 int ) </p><p>  初始條件:前者為已存在的集合,后者為集合中的元素; 操作結(jié)果:查找函數(shù),確定后者所屬子集; </p><p>  Swapn(edge *, int, int) </p><p>  初始條件: 圖G存在,各邊權(quán)值已知; 

24、</p><p>  操作結(jié)果:交換某兩個(gè)邊的權(quán)值;</p><p><b>  2.圖的存儲(chǔ)結(jié)構(gòu)</b></p><p>  typedef struct</p><p><b>  { </b></p><p>  int vexnum,arcnum;</p>

25、<p><b>  }ALGraph;</b></p><p>  typedef struct //邊的結(jié)構(gòu)體定義</p><p><b>  { </b></p><p>  int begin,end; //邊的開(kāi)始和結(jié)束頂點(diǎn)</p><p>  int cost; //權(quán)值&

26、lt;/p><p><b>  }EDGE;</b></p><p>  typedef struct</p><p><b>  {</b></p><p>  int edges[max][max];//</p><p><b>  int n,e;</b&g

27、t;</p><p><b>  }MGraph;</b></p><p><b>  3.流程圖</b></p><p><b>  五、詳細(xì)設(shè)計(jì)</b></p><p>  在該函數(shù)中有6個(gè)模塊,分別是主函數(shù)模塊、路徑權(quán)值進(jìn)行排序、交換頂點(diǎn)及權(quán)值模塊、判斷是否回環(huán)、prim

28、算法的實(shí)現(xiàn)、Kruskal算法的實(shí)現(xiàn)。</p><p><b>  1.主函數(shù)模塊</b></p><p>  ALGraph G;</p><p>  MGraph G2;</p><p>  int v,i,j;</p><p><b>  char a;</b><

29、/p><p><b>  do</b></p><p><b>  {</b></p><p>  system("cls");</p><p>  cout<<"\t***********************************\n\n";&

30、lt;/p><p>  cout<<"\t 1 克魯斯卡爾 \n";</p><p>  cout<<"\t 2 普 里 姆 \n";</p><p>  cout<<"\t

31、3 退 出 \n\n";</p><p>  cout<<"\t***********************************\n";</p><p>  cout<<"請(qǐng)輸入序號(hào):";</p><p><b>  cin>>a;&l

32、t;/b></p><p><b>  switch(a)</b></p><p><b>  {</b></p><p>  case '1': MiniSpanTree_Kruskal(G);system("pause");break;</p><p>

33、  case '2': cout<<"請(qǐng)輸入結(jié)點(diǎn)數(shù):";</p><p>  cin>>G2.n;</p><p>  for(j=1;j<=G2.n;j++)</p><p><b>  {</b></p><p>  cout<<"

34、;請(qǐng)輸入第"<<j<<"個(gè)頂點(diǎn)所有邊的權(quán)值(100代表不連通):";</p><p>  for(i=1;i<=G2.n;i++)</p><p>  cin>>G2.edges[j][i];</p><p><b>  }</b></p><p>

35、  cout<<"請(qǐng)輸入開(kāi)始頂點(diǎn):";</p><p><b>  cin>>v;</b></p><p>  MiniSpanTree_PRTM(G2,v);system("pause");break;</p><p>  default : break;</p>

36、<p><b>  }</b></p><p>  }while(a!='3');</p><p><b>  return 0;</b></p><p>  該模塊包含菜單的設(shè)計(jì)以及通過(guò)一個(gè)switch語(yǔ)句來(lái)實(shí)現(xiàn)對(duì)prim算法和Kruskal算法的實(shí)現(xiàn)。進(jìn)入主菜單后選擇相應(yīng)的序號(hào)執(zhí)行相應(yīng)的操作,

37、每進(jìn)行一步后,按任意鍵繼續(xù)進(jìn)行下一個(gè)操作可重復(fù)執(zhí)行。</p><p>  2.對(duì)路徑權(quán)值進(jìn)行排序</p><p>  void Sort(EDGE *edges,ALGraph G)</p><p>  //對(duì)帶權(quán)路徑從小到大排序</p><p><b>  {</b></p><p><b

38、>  int i,j;</b></p><p>  for(i=1;i<=G.arcnum;i++)</p><p>  for(j=i;j<=G.arcnum;j++)</p><p>  if(edges[i].cost>edges[j].cost)</p><p>  Swapn(edges,i,j)

39、;</p><p><b>  }</b></p><p>  在圖中找到權(quán)值最小的邊</p><p><b>  3.交換頂點(diǎn)及權(quán)值</b></p><p>  void Swapn(EDGE *edges,int i,int j)// 交換的兩個(gè)頂點(diǎn)及權(quán)值</p><p>

40、;<b>  {</b></p><p><b>  int temp;</b></p><p>  temp=edges[i].begin;</p><p>  edges[i].begin=edges[j].begin;</p><p>  edges[j].begin=temp;</p&

41、gt;<p>  temp=edges[i].end;</p><p>  edges[i].end=edges[j].end;</p><p>  edges[j].end=temp;</p><p>  temp=edges[i].cost;</p><p>  edges[i].cost=edges[j].cost;<

42、;/p><p>  edges[j].cost=temp;</p><p><b>  }</b></p><p>  該模塊主要用于Kruskal算法,找到圖中權(quán)值最小的一條邊,然后交換它們的頂點(diǎn)和權(quán)值。</p><p><b>  4.判斷是否回環(huán)</b></p><p> 

43、 int Find(int *parents,int f)</p><p><b>  //判斷是否形成環(huán)</b></p><p><b>  {</b></p><p>  while((parents[f])>0&&(f!=parents[f]))</p><p>  f=

44、parents[f];</p><p><b>  return f;</b></p><p><b>  }</b></p><p>  在Kruskal算法中初始parents[]為0來(lái)設(shè)置訪問(wèn)未訪問(wèn)標(biāo)志,以此來(lái)判斷圖是否成環(huán)。</p><p>  5.prim算法的實(shí)現(xiàn)</p>

45、<p>  void MiniSpanTree_PRTM(MGraph &G,int v)</p><p><b>  {</b></p><p>  int closedge[max];</p><p>  int lowcost[max];</p><p>  int i,j,k,min;</

46、p><p>  for(i=1;i<=G.n;i++)</p><p><b>  {</b></p><p>  lowcost[i]=G.edges[v][i];</p><p>  closedge[i]=v;</p><p><b>  }</b></p>

47、;<p>  for(i=1;i<G.n;i++)</p><p><b>  {</b></p><p><b>  min=INF;</b></p><p>  for(j=1;j<=G.n;j++)</p><p>  if(lowcost[j]!=0&&am

48、p;lowcost[j]<min)</p><p><b>  {</b></p><p>  min=lowcost[j];</p><p><b>  k=j;</b></p><p><b>  }</b></p><p>  printf(

49、"邊(%d,%d)權(quán)為:%d\n",closedge[k],k,min);</p><p>  lowcost[k]=0;</p><p>  for(j=1;j<=G.n;j++)</p><p>  if(G.edges[k][j]!=0&&G.edges[k][j]<lowcost[j])</p>

50、<p><b>  {</b></p><p>  lowcost[j]=G.edges[k][j];</p><p>  closedge[j]=k;</p><p><b>  }</b></p><p><b>  }</b></p><p&

51、gt;<b>  }</b></p><p>  6.Kruskal算法的實(shí)現(xiàn)</p><p>  void MiniSpanTree_Kruskal(ALGraph &G)</p><p>  //MiniSpanTree_Kruskal()函數(shù)實(shí)現(xiàn)</p><p><b>  {</b>

52、</p><p>  int i,s,v1,v2,value,bnf,edf;</p><p>  int parents[MAX_VERTEX_NUM]; </p><p>  EDGE edges[MAX_VERTEX_NUM];</p><p>  cout<<endl<<"請(qǐng)輸入頂點(diǎn)數(shù): &q

53、uot;;</p><p>  cin>>G.vexnum; //輸入頂點(diǎn)數(shù)</p><p>  cout<<"請(qǐng)輸入邊數(shù): ";</p><p>  cin>>G.arcnum; //輸入邊數(shù)</p><p>  cout<<&q

54、uot;請(qǐng)輸入(V1和V2), 例如: (V1=1,V2=3),(V1=2,V2=4)...";</p><p>  cout<<endl; //輸入arc(v1,v2)</p><p>  for(i=1;i<=G.arcnum;++i)</p><p><b>  {</b><

55、/p><p>  cout<<endl<<"請(qǐng)輸入第 "<<i<<"條邊的第一個(gè)頂點(diǎn): ";</p><p>  cin>>v1; //輸入頭頂點(diǎn)</p><p>  cout<<"請(qǐng)輸入第 "<<

56、i<<"條邊的第二個(gè)頂點(diǎn): ";</p><p>  cin>>v2; //輸入尾頂點(diǎn)</p><p>  cout<<"請(qǐng)輸入第 "<<i<<"條邊的權(quán)值 : ";</p><p>  cin>>

57、;value; //輸入邊的權(quán)值</p><p>  edges[i].begin=v1;</p><p>  edges[i].end=v2;</p><p>  while(v1<1||v1>G.vexnum||v2<1||v2>G.vexnum) //如果輸入的非法,重新輸入</p><p&

58、gt;<b>  {</b></p><p>  cout<<"輸入不合法,請(qǐng)重新輸入!";</p><p>  cout<<endl<<"請(qǐng)輸入第 "<<i<<"條邊的第一個(gè)頂點(diǎn): ";</p><p><b> 

59、 cin>>v1;</b></p><p>  cout<<"請(qǐng)輸入第 "<<i<<"條邊的第二個(gè)頂點(diǎn): ";</p><p><b>  cin>>v2;</b></p><p>  cout<<"請(qǐng)輸入第 &

60、quot;<<i<<"條邊的權(quán)值 : ";</p><p>  cin>>value;</p><p>  edges[i].begin=v1;</p><p>  edges[i].end=v2;</p><p><b>  }</b></p>

61、;<p>  edges[i].cost=value;</p><p><b>  } </b></p><p>  Sort(edges,G); //調(diào)用Sort()函數(shù)</p><p>  cout<<"按照排列好的序列逐個(gè)輸出權(quán)值"<<endl;

62、</p><p>  for(i=1;i<=G.arcnum;i++)</p><p>  cout<<edges[i].cost<<"\t";</p><p>  for(i=1;i<=G.vexnum;++i)</p><p>  parents[i]=0; /

63、/初始化array parents[]</p><p>  cout<<endl<<"最小生成樹(shù)為:"<<endl;</p><p>  for(i=1,s=1;s<=G.vexnum&&i<=G.arcnum;i++)</p><p><b>  { </b>

64、</p><p>  bnf=Find(parents,edges[i].begin);</p><p>  edf=Find(parents,edges[i].end);</p><p>  if(bnf!=edf)</p><p><b>  {</b></p><p>  parents[b

65、nf]=edf;</p><p>  cout<<endl<<edges[i].begin<<"-"; //輸出最小生成樹(shù)</p><p>  cout<<edges[i].end<<"的邊為:";</p><p>  cout<<edges[i].

66、cost;</p><p><b>  s++;</b></p><p><b>  } </b></p><p><b>  } </b></p><p><b>  }</b></p><p><b>  六、調(diào)試與分

67、析</b></p><p><b>  測(cè)試數(shù)據(jù)如下圖</b></p><p><b>  求該圖的最小生成樹(shù)</b></p><p><b>  1.進(jìn)入主頁(yè)面</b></p><p>  2.利用克魯斯卡爾算法求最小生成樹(shù)</p><p>

68、;  選擇序號(hào)1使用克魯斯卡爾算法求圖的最小生成樹(shù)。</p><p>  輸入每條邊的頂點(diǎn)和權(quán)值</p><p>  對(duì)權(quán)值進(jìn)行排序,并且輸出最小生成樹(shù)。</p><p>  3.利用prim算法求最小生成樹(shù)</p><p>  選擇序號(hào)2用prim算法求最小生成樹(shù)。</p><p>  通過(guò)一個(gè)n階的鄰接矩陣來(lái)實(shí)現(xiàn)圖

69、的輸入</p><p>  輸入起始頂點(diǎn)然后輸出最小生成樹(shù)的各邊及其每一條邊的權(quán)值。</p><p><b>  4.退出程序</b></p><p><b>  選擇序號(hào)3退出程序</b></p><p><b>  七、測(cè)試結(jié)果</b></p><p&g

70、t;  克魯斯卡爾算法求得的最小生成樹(shù)為352146</p><p>  Prim算法求得的最小生成樹(shù)為125346</p><p><b>  八、設(shè)計(jì)心得體會(huì)</b></p><p>  在我的努力下,課程設(shè)計(jì)終于完成,由于我們對(duì)數(shù)據(jù)結(jié)構(gòu)和c語(yǔ)言不是很了解,有時(shí)忽略了一些關(guān)鍵的細(xì)節(jié),使得在編寫(xiě)程序的過(guò)程中出現(xiàn)了一些問(wèn)題。對(duì)于打字有時(shí)粗心導(dǎo)致

71、出現(xiàn)一些難以發(fā)現(xiàn)的小錯(cuò)誤,在我的耐心,細(xì)致的調(diào)試下最終使得程序能夠運(yùn)行,課程設(shè)計(jì)圓滿(mǎn)完工。 </p><p>  問(wèn)題一:求出圖中的最小值  </p><p>  現(xiàn)象:求出的最小值是0 </p><p>  原因:圖中沒(méi)有連通的兩個(gè)頂點(diǎn)之間的權(quán)值賦值為0</p><p>  問(wèn)題二:求最小生成樹(shù)時(shí),e

72、lse語(yǔ)句需再調(diào)用一個(gè)函數(shù)  </p><p>  現(xiàn)象:對(duì)某些二叉樹(shù)能求出最小生成樹(shù),但不能普遍適應(yīng) </p><p>  原因:對(duì)于找最小生成樹(shù)邊的各種可能沒(méi)有考慮全面,代碼才沒(méi)有廣泛的適應(yīng)性 </p><p>  問(wèn)題三:兩個(gè)頂點(diǎn)之間的邊是否是最小生成樹(shù)的邊 </p><p>  現(xiàn)象:

73、代碼的功能不能分辨出是否是最小生成樹(shù)的邊 </p><p>  原因:把簡(jiǎn)單的代碼寫(xiě)的很復(fù)雜,從而雜亂無(wú)章出現(xiàn)錯(cuò)誤。</p><p>  在課設(shè)過(guò)程中,遇到許多問(wèn)題,通過(guò)查閱資料和課本。是我對(duì)數(shù)據(jù)結(jié)構(gòu)有了更進(jìn)一步的認(rèn)識(shí)。當(dāng)然,這中間也有其他人的幫助。我的同學(xué),以及指導(dǎo)老師都給我提出了非常寶貴的意見(jiàn)。通過(guò)與同學(xué)和老師的交流,使我找到了數(shù)據(jù)結(jié)構(gòu)這門(mén)課程的學(xué)習(xí)方法。但是,我感覺(jué)這不僅僅

74、是數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)方法,他或許就是學(xué)習(xí)軟件工程這門(mén)專(zhuān)業(yè)的方法,那就是多動(dòng)手。的確如此,對(duì)于一個(gè)算法,你知道它的算法思想和用計(jì)算機(jī)實(shí)現(xiàn)它卻是另外一回事。這門(mén)課程,不僅需要我們用心去理解每一種算法的思想,更需要我們?nèi)?dòng)手來(lái)實(shí)現(xiàn)它。</p><p><b>  附錄(源代碼)</b></p><p>  #include "iostream"</p&

75、gt;<p>  using namespace std;</p><p>  #define MAX_VERTEX_NUM 30 //定義最大頂點(diǎn)數(shù)</p><p>  #define MAXQSIZE 100</p><p>  #define max 20</p><p>  #define INF 10</p>

76、;<p>  typedef struct</p><p><b>  { </b></p><p>  int vexnum,arcnum;</p><p><b>  }ALGraph;</b></p><p>  typedef struct //邊的結(jié)構(gòu)體定義</p>

77、;<p><b>  { </b></p><p>  int begin,end; //邊的開(kāi)始和結(jié)束頂點(diǎn)</p><p>  int cost; //權(quán)值</p><p><b>  }EDGE;</b></p><p>  ///////////////////////////

78、///</p><p>  typedef struct</p><p><b>  {</b></p><p>  int edges[max][max];//</p><p><b>  int n,e;</b></p><p><b>  }MGraph;&l

79、t;/b></p><p>  void Swapn(EDGE *edges,int i,int j); // 交換的兩個(gè)頂點(diǎn)及權(quán)值</p><p>  void Sort(EDGE *edges,ALGraph G); //對(duì)帶權(quán)路徑從小到大排序</p><p>  int Find(int *parents,int f);

80、 //判斷是否形成環(huán)</p><p>  void MiniSpanTree_Kruskal(ALGraph &G); //MiniSpanTree_Kruskal()函數(shù)實(shí)現(xiàn)</p><p>  void Swapn(EDGE *edges,int i,int j)// 交換的兩個(gè)頂點(diǎn)及權(quán)值</p><p><b>  {</b>

81、;</p><p><b>  int temp;</b></p><p>  temp=edges[i].begin;</p><p>  edges[i].begin=edges[j].begin;</p><p>  edges[j].begin=temp;</p><p>  temp=e

82、dges[i].end;</p><p>  edges[i].end=edges[j].end;</p><p>  edges[j].end=temp;</p><p>  temp=edges[i].cost;</p><p>  edges[i].cost=edges[j].cost;</p><p>  ed

83、ges[j].cost=temp;</p><p><b>  }</b></p><p>  void Sort(EDGE *edges,ALGraph G)</p><p>  //對(duì)帶權(quán)路徑從小到大排序</p><p><b>  {</b></p><p><b

84、>  int i,j;</b></p><p>  for(i=1;i<=G.arcnum;i++)</p><p>  for(j=i;j<=G.arcnum;j++)</p><p>  if(edges[i].cost>edges[j].cost)</p><p>  Swapn(edges,i,j)

85、;</p><p><b>  }</b></p><p>  int Find(int *parents,int f)</p><p><b>  //判斷是否形成環(huán)</b></p><p><b>  {</b></p><p>  while((p

86、arents[f])>0&&(f!=parents[f]))</p><p>  f=parents[f];</p><p><b>  return f;</b></p><p><b>  }</b></p><p>  void MiniSpanTree_Kruskal(

87、ALGraph &G)</p><p>  //MiniSpanTree_Kruskal()函數(shù)實(shí)現(xiàn)</p><p><b>  {</b></p><p>  int i,s,v1,v2,value,bnf,edf;</p><p>  int parents[MAX_VERTEX_NUM]; <

88、/p><p>  EDGE edges[MAX_VERTEX_NUM];</p><p>  cout<<endl<<"請(qǐng)輸入頂點(diǎn)數(shù): ";</p><p>  cin>>G.vexnum; //輸入頂點(diǎn)數(shù)</p><p>  cout<<"請(qǐng)輸入

89、邊數(shù): ";</p><p>  cin>>G.arcnum; //輸入邊數(shù)</p><p>  cout<<"請(qǐng)輸入(V1和V2), 例如: (V1=1,V2=3),(V1=2,V2=4)...";</p><p>  cout<<endl; //

90、輸入arc(v1,v2)</p><p>  for(i=1;i<=G.arcnum;++i)</p><p><b>  {</b></p><p>  cout<<endl<<"請(qǐng)輸入第 "<<i<<"條邊的第一個(gè)頂點(diǎn): ";</p>

91、<p>  cin>>v1; //輸入頭頂點(diǎn)</p><p>  cout<<"請(qǐng)輸入第 "<<i<<"條邊的第二個(gè)頂點(diǎn): ";</p><p>  cin>>v2; //輸入尾頂點(diǎn)</p><p&g

92、t;  cout<<"請(qǐng)輸入第 "<<i<<"條邊的權(quán)值 : ";</p><p>  cin>>value; //輸入邊的權(quán)值</p><p>  edges[i].begin=v1;</p><p>  edges[i].end=v2;<

93、/p><p>  while(v1<1||v1>G.vexnum||v2<1||v2>G.vexnum) //如果輸入的非法,重新輸入</p><p><b>  {</b></p><p>  cout<<"輸入不合法,請(qǐng)重新輸入!";</p><p>  cou

94、t<<endl<<"請(qǐng)輸入第 "<<i<<"條邊的第一個(gè)頂點(diǎn): ";</p><p><b>  cin>>v1;</b></p><p>  cout<<"請(qǐng)輸入第 "<<i<<"條邊的第二個(gè)頂點(diǎn): &

95、quot;;</p><p><b>  cin>>v2;</b></p><p>  cout<<"請(qǐng)輸入第 "<<i<<"條邊的權(quán)值 : ";</p><p>  cin>>value;</p><p>  

96、edges[i].begin=v1;</p><p>  edges[i].end=v2;</p><p><b>  }</b></p><p>  edges[i].cost=value;</p><p><b>  } </b></p><p>  Sort(edges

97、,G); //調(diào)用Sort()函數(shù)</p><p>  cout<<"按照排列好的序列逐個(gè)輸出權(quán)值"<<endl;</p><p>  for(i=1;i<=G.arcnum;i++)</p><p>  cout<<edges[i].cost<<"

98、;\t";</p><p>  for(i=1;i<=G.vexnum;++i)</p><p>  parents[i]=0; //初始化array parents[]</p><p>  cout<<endl<<"最小生成樹(shù)為:"<<endl;</p>&

99、lt;p>  for(i=1,s=1;s<=G.vexnum&&i<=G.arcnum;i++)</p><p><b>  { </b></p><p>  bnf=Find(parents,edges[i].begin);</p><p>  edf=Find(parents,edges[i].end);&

100、lt;/p><p>  if(bnf!=edf)</p><p><b>  {</b></p><p>  parents[bnf]=edf;</p><p>  cout<<endl<<edges[i].begin<<"-"; //輸出最小生成樹(shù)</p&

101、gt;<p>  cout<<edges[i].end<<"的邊為:";</p><p>  cout<<edges[i].cost;</p><p><b>  s++;</b></p><p><b>  } </b></p><

102、p><b>  } </b></p><p><b>  }</b></p><p>  ///////////////////////</p><p>  void MiniSpanTree_PRTM(MGraph &G,int v)</p><p><b>  {<

103、/b></p><p>  int closedge[max];</p><p>  int lowcost[max];</p><p>  int i,j,k,min;</p><p>  for(i=1;i<=G.n;i++)</p><p><b>  {</b></p&g

104、t;<p>  lowcost[i]=G.edges[v][i];</p><p>  closedge[i]=v;</p><p><b>  }</b></p><p>  for(i=1;i<G.n;i++)</p><p><b>  {</b></p>&

105、lt;p><b>  min=INF;</b></p><p>  for(j=1;j<=G.n;j++)</p><p>  if(lowcost[j]!=0&&lowcost[j]<min)</p><p><b>  {</b></p><p>  min=l

106、owcost[j];</p><p><b>  k=j;</b></p><p><b>  }</b></p><p>  printf("邊(%d,%d)權(quán)為:%d\n",closedge[k],k,min);</p><p>  lowcost[k]=0;</p&g

107、t;<p>  for(j=1;j<=G.n;j++)</p><p>  if(G.edges[k][j]!=0&&G.edges[k][j]<lowcost[j])</p><p><b>  {</b></p><p>  lowcost[j]=G.edges[k][j];</p>

108、<p>  closedge[j]=k;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  int main()</p><p><b>  {

109、</b></p><p>  ALGraph G;</p><p>  MGraph G2;</p><p>  int v,i,j;</p><p><b>  char a;</b></p><p><b>  do</b></p><p&

110、gt;<b>  {</b></p><p>  system("cls");</p><p>  cout<<"\t***********************************\n\n";</p><p>  cout<<"\t 1 克魯

111、斯卡爾 \n";</p><p>  cout<<"\t 2 普 里 姆 \n";</p><p>  cout<<"\t 3 退 出 \n\n";</p><p>  cou

112、t<<"\t***********************************\n";</p><p>  cout<<"請(qǐng)輸入序號(hào):";</p><p><b>  cin>>a;</b></p><p><b>  switch(a)</b>

113、;</p><p><b>  {</b></p><p>  case '1': MiniSpanTree_Kruskal(G);system("pause");break;</p><p>  case '2': cout<<"請(qǐng)輸入結(jié)點(diǎn)數(shù):";</p

114、><p>  cin>>G2.n;</p><p>  for(j=1;j<=G2.n;j++)</p><p><b>  {</b></p><p>  cout<<"請(qǐng)輸入第"<<j<<"個(gè)頂點(diǎn)所有邊的權(quán)值(100代表不連通):&quo

115、t;;</p><p>  for(i=1;i<=G2.n;i++)</p><p>  cin>>G2.edges[j][i];</p><p><b>  }</b></p><p>  cout<<"請(qǐng)輸入開(kāi)始頂點(diǎn):";</p><p>&l

116、t;b>  cin>>v;</b></p><p>  MiniSpanTree_PRTM(G2,v);system("pause");break;</p><p>  default : break;</p><p><b>  }</b></p><p>  }whi

溫馨提示

  • 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ù)僅提供信息存儲(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)論