數(shù)據(jù)結(jié)構(gòu)課程設計-最小生成樹_第1頁
已閱讀1頁,還剩16頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、<p><b>  目 錄</b></p><p>  一、設計目的……………………………………………………………….-2-</p><p>  二、算法思想分析………………………………………………………-2-</p><p>  1.算法思想………………………………………………………………..-3-</p><

2、p>  1)普里姆(Prim)算法思想……………………………………………………….-3-</p><p>  2)克魯斯卡爾(Kruskal)算法思想..........................................-3-</p><p>  2.系統(tǒng)采用的數(shù)據(jù)結(jié)構(gòu)和算法………………………………-3-</p><p>  三、算法的描述與實

3、現(xiàn)……………………………………………….-4-</p><p>  四、用戶手冊………………………………………………………………-7-</p><p>  五、總結(jié)…………………………………………………………………….-10-</p><p>  六、參考文獻…………………………………………………………….-10-</p><p>  七、附

4、錄(源代碼)………………………………………………...-10-</p><p>  [摘要] 選擇一顆生成樹,使之總的消費最少,也就是要構(gòu)造連通網(wǎng)的最小代價生成樹(簡稱為最小生成樹)的問題,一顆生成樹的代價就是樹上各邊的代價之和,構(gòu)造最小生成樹可以有多種算法,其中多數(shù)算法利用了MST的性質(zhì)。</p><p>  關鍵詞:最小生成樹 連通圖 普里姆算法 克魯斯卡爾算法 MST</p&g

5、t;<p><b>  設計目的</b></p><p>  了解并掌握數(shù)據(jù)結(jié)構(gòu)與算法的設計方法,具備初步的獨立分析和設計能力;</p><p>  初步掌握軟件開發(fā)過程的問題分析、系統(tǒng)設計、程序編碼、測試等基本方法和技能;</p><p>  提高綜合運用所學的理論知識和方法獨立分析和解決問題的能力;</p>&l

6、t;p>  訓練用系統(tǒng)的觀點和軟件開發(fā)一般規(guī)范進行軟件開發(fā),培養(yǎng)軟件工作者所應具備的科學的工作方法和作風。</p><p><b>  算法思想分析</b></p><p>  該設計的要求是在n個城市之間建設網(wǎng)絡,不僅要保證連通,還要求是最經(jīng)濟的架設方法。根據(jù)克魯斯卡爾和普里姆算法的不同之處,該程序?qū)⒊鞘袀€數(shù)大于十個時應用普里姆算法求最小生成樹,而城市個數(shù)小于

7、十個時則應用克魯斯卡爾進行計算。</p><p><b>  算法思想</b></p><p>  普里姆(Prim)算法思想</p><p>  選擇從0節(jié)點開始,并選擇0節(jié)點相關聯(lián)的最小權值邊,將與這條邊相關聯(lián)的另一頂點出列;</p><p>  在出列的節(jié)點中相關聯(lián)的所有邊中選擇一條不與另一個已出列的節(jié)點相關聯(lián)的權

8、值最小的邊,并將該邊相關聯(lián)的節(jié)點出列;</p><p>  重復b)直到所有的節(jié)點出列。</p><p>  克魯斯卡爾(Kruskal)算法思想</p><p>  為了使生成樹上總的權值之和最小,應該使每一條邊上的權值盡可能的小,所以應從權值最小的邊選起,直至選出n-1條不能構(gòu)成回路的權值最小的邊位置。</p><p>  具體做法如下:

9、首先構(gòu)造一個含n個頂點的森林,然后按權值從小到大從連通圖中選擇不使森林中產(chǎn)生回路的邊加入到森林中去,直至該森林變成一棵樹為止,這棵樹便是連通圖的最小生成樹。</p><p>  由于生成樹上不允許有回路,因此并非每一條居當前最小的邊都可選。從生成樹的構(gòu)造過程可見,初始態(tài)為n個頂點分屬n棵樹,互不連通,每加入一條邊,就將兩棵樹合并為一棵樹,在同一棵樹上的兩個頂點之間自然相連通,由此判別當前權值最小邊是否可取只要判別

10、它的兩個頂點是否在同一棵樹上即可。</p><p>  系統(tǒng)采用的數(shù)據(jù)結(jié)構(gòu)和算法</p><p><b>  數(shù)據(jù)結(jié)構(gòu)</b></p><p>  Typedef int Vertextype;</p><p>  Typedef int adimatrix[MaxVertexNum][MaxVertexNum];<

11、;/p><p>  Typedef int Vertextype vexlist[MaxVertexNum];</p><p>  Typedef int VexType;</p><p>  Typedef int AdjType;</p><p>  Typedef struct edgeElem edgeset[MaxVertexNum];

12、</p><p>  struct edgeElem</p><p>  {int fromvex;//頭頂點</p><p>  int endvex;//尾頂點</p><p>  int weight;//權</p><p><b>  };</b></p><p>

13、  Typedef struct</p><p>  {int n;//圖的頂點個數(shù)</p><p>  AdjType acrs[MAXVEX][MAXVEX];//邊信息</p><p>  }GraphMatrix;</p><p>  Typedef struct</p><p>  {int start_ve

14、x,stop_vex;//邊的起點和終點</p><p>  AdjType weight;//邊的權</p><p><b>  }Edge;</b></p><p>  Edge mst[5];</p><p><b>  算法</b></p><p>  Great_a

15、djmatrix();</p><p>  Great_adjmatrix2();</p><p>  Kruskal();</p><p>  out_edgeaet();</p><p><b>  prim();</b></p><p><b>  算法的描述與實現(xiàn)</b&g

16、t;</p><p>  Great_adjmatrix()和Great_adjmatrix2()是兩種建立圖的方法;</p><p>  克魯斯卡爾算法(Kruskal):</p><p>  Void kruskal(GraphMatrix * pgraph,Edge mst[])</p><p>  {int i,j,min,vx,vy

17、;</p><p>  int weight,minweight;</p><p>  Edge edge;</p><p>  for(i=0;i<pgraph->n-1;i++)</p><p>  {mst[i].start_vex = 0;</p><p>  Mst[i].stop_vex = i

18、+1;</p><p>  Mst[i].weight = pgraph->arcs[0][i+1];</p><p><b>  }</b></p><p>  for(i=0;i<pgraph->n-1;i++)//共n-1條邊</p><p>  {minweight = MAX;</p&g

19、t;<p><b>  min = i;</b></p><p>  for(j=i;j<pgraph->n-1;j++)</p><p>  //從所有(vx,vy)(vx∈U,vy∈V-U)中選出最短的邊</p><p>  if(mst[j].weight<minweight)</p>&l

20、t;p>  {minweight = mst[j].weight;</p><p><b>  min = j;</b></p><p><b>  }</b></p><p>  //mst[min]是最短的邊(vx,vy)(vx∈U,vy∈V-U),將mst[min]加入最小生成樹</p><

21、p>  edge = mst[min];</p><p>  mst[min] = mst[i];</p><p>  mst[i] = edge;</p><p>  vx = mst[i].stop_vex;//vx為剛加入最小生成樹的頂點的下標</p><p>  for(j=i+1;j<pgraph->n-1;j++

22、)</p><p>  {vy=mst[j].stop_vex;weight=pgraph->arcs[vx][vy];</p><p>  if(weight<mst[j].weight)</p><p>  {mst[j].weight=weight;</p><p>  mst[j].start_vex = vx;</

23、p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  普里姆算法(Prim):</p><p&

24、gt;  void prim(adjmatrix GA,edgeset MST,int n)</p><p>  //利用prim算法從0點出發(fā)求圖的最小生成樹</p><p> ?。鹖nt i,j,t,k,w,min,m;</p><p>  struct edgeElem x;</p><p>  for(i=0;i<n;i++)&

25、lt;/p><p>  if(i>0) //從0點連接其余頂點</p><p> ?。鸐ST[i-1].fromvex=0;</p><p>  MST[i-1].endvex=i;</p><p>  MST[i-1].weight=GA[0][i];</p><p><b>  }</b>

26、</p><p>  for(k=1;k<n;k++)</p><p>  {min=MaxValue;</p><p><b>  m=k-1;</b></p><p>  for(j=k-1;j<n-1;j++)</p><p>  if(MST[j].weight<min)

27、</p><p>  {min=MST[j].weight;</p><p><b>  M=j;</b></p><p>  }//選擇從0點出發(fā)權值最小的邊</p><p>  x=MST[k-1];MST[k-1]=MST[m];MST[m]=x;//交換位置</p><p>  j=MST

28、[k-1].endvex;//定位于權值最小邊的尾頂點</p><p>  for(i=k;i<n-1;i++)//選取輕邊</p><p>  {t=MST[i].endvex;</p><p>  w=GA[j][t];</p><p>  if(w<MST[i].weight)</p><p>  {

29、MST[i].weight=w;</p><p>  MST[i].fromvex=j;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }&l

30、t;/b></p><p>  out_edgeset()功能為顯示最小生成樹。</p><p><b>  用戶手冊</b></p><p>  1.運行程序,得到如下窗口:</p><p>  2.輸入頂點數(shù),選擇算法:</p><p>  1)當輸入的頂點數(shù)小于10時,選擇Kruska

31、l算法,如下圖</p><p>  2)當輸入的頂點數(shù)大于10時,選擇Prim算法,如下圖</p><p><b>  五、總結(jié)</b></p><p>  該程序?qū)崿F(xiàn)了在n個城市之間建設網(wǎng)絡,既保證了連通性,也成為了最經(jīng)濟的架設方法。程序中應用了普里姆算法和克魯斯卡爾算法,實現(xiàn)了矩陣的輸出以及最小生成樹的輸出。不過,該程序仍有不足之處,圖的輸

32、入數(shù)據(jù)過大,易出錯,不易返回,仍需完善。</p><p><b>  六、參考文獻</b></p><p>  [1] 《數(shù)據(jù)結(jié)構(gòu)程序設計題典》 李春葆編 清華大學出版社</p><p>  [2] 《數(shù)據(jù)結(jié)構(gòu)(C語言版)》 嚴蔚敏 吳偉民編 清華大學出版社</p><p>  [3] 《數(shù)據(jù)結(jié)構(gòu)課程設計》 蘇仕華編 機

33、械工業(yè)出版社</p><p>  七、附錄:(源代碼)</p><p>  #include<stdio.h></p><p>  #include<stdlib.h></p><p>  #define MaxVertexNum 12</p><p>  #define MaxEdgeN

34、um 20</p><p>  #define MaxValue 1000</p><p>  #define MAXVEX 6</p><p>  #define MAX 1e+8</p><p>  typedef int Vertextype;</p><p>  typedef int adjmatrix[Ma

35、xVertexNum][MaxVertexNum];</p><p>  typedef Vertextype vexlist[MaxVertexNum];</p><p>  typedef int VexType;</p><p>  typedef int AdjType;</p><p>  typedef struct edgeEl

36、em edgeset[MaxVertexNum]; </p><p>  struct edgeElem</p><p>  {int fromvex;//頭頂點</p><p>  int endvex;//尾頂點</p><p>  int weight;//權</p><p><b>  };</

37、b></p><p>  typedef struct {</p><p>  int n; /* 圖的頂點個數(shù) */</p><p>  /*VexType vexs[MAXVEX]; 頂點信息 */</p><p>  AdjType arcs[MAXVEX][MAX

38、VEX]; /* 邊信息 */</p><p>  } GraphMatrix;</p><p>  typedef struct{</p><p>  int start_vex, stop_vex; /* 邊的起點和終點 */</p><p>  AdjType weight; /* 邊的

39、權 */</p><p>  } Edge;Edge mst[5];</p><p>  void Creat_adjmatrix(vexlist GV,adjmatrix GA,int n,int e)</p><p>  { int i,j,k,w;</p><p>  printf("輸入%d個頂點序號(0--n-1):

40、",n);</p><p>  for(i=0;i<n;i++) //建立頂點表</p><p>  scanf("%d",&GV[i]);//讀入頂點信息</p><p>  for(i=0;i<n;i++)//建立邊表</p><p>  for(j=0;j<n;j++)//初始化邊

41、表</p><p>  if(i==j) GA[i][j]=0;</p><p>  else GA[i][j]=MaxValue;</p><p>  printf("輸入%d條無向帶權邊(序號 序號 權值):\n",e);</p><p>  for(k=0;k<e;k++)//設置邊表</p>&

42、lt;p>  { scanf("%d%d%d",&i,&j,&w);</p><p>  GA[i][j]=GA[j][i]=w;//對稱</p><p><b>  }</b></p><p><b>  }</b></p><p>  vo

43、id Creat_adjmatrix2(vexlist GV,adjmatrix GA,int m,int e,GraphMatrix &graph)</p><p>  { int i,j,k,w,x,y;</p><p>  printf("輸入%d個頂點序號(0-m-1),序號從0開始。",m);</p><p>  for(

44、i=0;i<m;i++) //建立頂點表</p><p>  {scanf("%d",&GV[i]);//讀入頂點信息</p><p>  if(GV[i]>=m) </p><p>  { printf("您輸入的序號有誤,請輸入0到%d-1之間的數(shù),請重新輸入。\n",m);</p>&l

45、t;p>  scanf("%d",&GV[i]);}</p><p><b>  }</b></p><p>  for(i=0;i<m;i++)//建立邊表</p><p>  for(j=0;j<m;j++)//初始化邊表</p><p>  GA[i][j]=MaxVa

46、lue;</p><p>  printf("請輸入有多少條邊。\n");</p><p>  scanf("%d",&e);</p><p>  printf("輸入%d條無向帶權邊(序號 序號 權值):\n",e);</p><p>  for(k=0;k<e;k+

47、+)//設置邊表</p><p>  { scanf("%d%d%d",&i,&j,&w);</p><p>  GA[i][j]=GA[j][i]=w;//對稱</p><p><b>  }</b></p><p>  printf("您輸入的圖的存貯為下面表,

48、如果不可達則用1000表示。\n");</p><p>  graph.n =m;</p><p>  for(x=0;x<m;x++)</p><p>  {for(y=0;y<m;y++) {</p><p>  graph.arcs[x][y]=GA[x][y];</p><p>  pri

49、ntf("%-4d ",graph.arcs[x][y]);}</p><p>  printf("\n");</p><p><b>  }</b></p><p><b>  }</b></p><p>  void kruskal(GraphMatri

50、x * pgraph, Edge mst[]) {</p><p>  int i, j, min, vx, vy; </p><p>  int weight, minweight; Edge edge;</p><p>  for (i = 0; i < pgraph->n-1; i++) {</p><p>  mst[i]

51、.start_vex = 0;</p><p>  mst[i].stop_vex = i+1;</p><p>  mst[i].weight = pgraph->arcs[0][i+1];</p><p><b>  }</b></p><p>  for (i = 0; i < pgraph->n

52、-1; i++) { /* 共n-1條邊 */</p><p>  minweight = MAX; min = i;</p><p>  for (j = i; j < pgraph->n-1; j++)/* 從所有邊(vx,vy)(vx∈U,vy∈V-U)中選出最短的邊 */</p><p>  if(mst[j].we

53、ight < minweight) {</p><p>  minweight = mst[j].weight; </p><p><b>  min = j;</b></p><p><b>  }</b></p><p>  /* mst[min]是最短的邊(vx,vy)(vx∈U, vy

54、∈V-U),將mst[min]加入最小生成樹 */</p><p>  edge = mst[min]; </p><p>  mst[min] = mst[i]; </p><p>  mst[i] = edge;</p><p>  vx = mst[i].stop_vex; /* vx為剛加入最小生成樹的頂點

55、的下標 */</p><p>  for(j = i+1; j < pgraph->n-1; j++) { /* 調(diào)整mst[i+1]到mst[n-1] */</p><p>  vy=mst[j].stop_vex; weight = pgraph->arcs[vx][vy];</p><p>  if (weight < mst[j].w

56、eight) {</p><p>  mst[j].weight = weight; </p><p>  mst[j].start_vex = vx;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }

57、</b></p><p><b>  }</b></p><p>  void out_edgeset(edgeset MST,int e)//顯示最小生成樹</p><p>  { int k;</p><p>  printf("最小的消耗路線為\n");</p>

58、<p>  for(k=0;k<e;k++)</p><p>  printf("(%d %d %d)\n",MST[k].fromvex,MST[k].endvex,MST[k].weight);</p><p><b>  }</b></p><p>  void prim(adjmatrix GA,ed

59、geset MST,int n)//利用prim算法從0點出發(fā)求圖的最小生成樹</p><p>  { int i,j,t,k,w,min,m;</p><p>  struct edgeElem x;</p><p>  for(i=0;i<n;i++)</p><p>  if(i>0)//從0點連接其余頂點</p

60、><p>  { MST[i-1].fromvex=0;</p><p>  MST[i-1].endvex=i;</p><p>  MST[i-1].weight=GA[0][i];</p><p><b>  }</b></p><p>  for(k=1;k<n;k++)<

61、/p><p>  { min=MaxValue;</p><p><b>  m=k-1;</b></p><p>  for(j=k-1;j<n-1;j++)</p><p>  if(MST[j].weight<min) {min=MST[j].weight;m=j;}//選擇從0點出發(fā)權值最小

62、的邊</p><p>  x=MST[k-1];MST[k-1]=MST[m];MST[m]=x;//交換位置</p><p>  j=MST[k-1].endvex;//定位于權值最小邊的尾頂點</p><p>  for(i=k;i<n-1;i++)//選取輕邊</p><p>  { t=MST[i].endvex;w=GA

63、[j][t];</p><p>  if(w<MST[i].weight)</p><p>  { MST[i].weight=w;</p><p>  MST[i].fromvex=j;</p><p><b>  }</b></p><p><b>  }</b&g

64、t;</p><p><b>  }</b></p><p><b>  } </b></p><p>  void main()</p><p><b>  {</b></p><p>  int n,e,i;</p><p>

65、;<b>  int a;</b></p><p>  system("color 71");//改變屏幕顏色</p><p>  printf(" ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");</p><p>  printf(" ┃㊣

66、 必做題:最小生成樹 ㊣┃\n");</p><p>  printf(" ┃ 姓名:xxxx ┃\n");</p><p>  printf(" ┃ 學號:xxxxxxxxx

67、 ┃\n");</p><p>  printf(" ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");</p><p>  vexlist GV;//頂點表</p><p>  adjmatrix GA;//邊表</p><p>  edgeset

68、 MST;//最小生成樹</p><p><b>  do{</b></p><p>  printf("輸入圖的頂點數(shù)n,我們將根據(jù)您輸入的數(shù)據(jù)大小選擇合適的算法。\n");</p><p>  scanf("%d",&n);</p><p>  if(n>=10)

69、//大于10用prim算法來實現(xiàn),否則kruskal算法來實現(xiàn)</p><p><b>  {</b></p><p>  printf("用prim算法從0點出發(fā)求圖的最小生成樹為:\n");</p><p>  printf("請輸入圖的邊數(shù)。\n");</p><p>  c

70、anf("%d",&e);</p><p>  Creat_adjmatrix( GV, GA, n, e);//創(chuàng)建圖</p><p>  prim(GA,MST,n);//生成最小生成樹</p><p>  out_edgeset( MST, n-1);//輸出最小生成樹</p><p><b>  

71、}</b></p><p><b>  else{</b></p><p>  printf("用kcuskal算法的最小生成樹為:\n");</p><p>  GraphMatrix graph;//定義一個結(jié)構(gòu)體來表示存儲結(jié)構(gòu)</p><p>  Creat_adjmatrix2(G

72、V,GA,n,e,graph);//創(chuàng)建圖</p><p>  kruskal(&graph,mst);//生成最小生成樹</p><p>  rintf("最小的消耗路線為\n");</p><p>  for (i = 0; i < graph.n-1; i++)</p><p>  printf(&qu

73、ot;(%d %d %d)\n", mst[i].start_vex,</p><p>  mst[i].stop_vex, mst[i].weight);//輸出最小生成樹</p><p><b>  }</b></p><p>  printf("謝謝使用!\n");</p><p> 

74、 printf("繼續(xù)?輸入1繼續(xù),輸入0退出。\n");//方便用戶重復使用</p><p>  scanf("%d",&a); </p><p>  getchar();</p><p>  system("cls");//清屏語句 </p><p>  }while(a

溫馨提示

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

評論

0/150

提交評論