最小生成樹

 最小生成樹:

n個頂點,用n-1條邊把一個連通圖連接起來,並且使得權值和最小。

  1. /* 
  2. *1.初始化兩個數組,一個用於存放邊權值,一個用來存放邊權值的起始點 
  3. *2.賦初值,從0開始,所有邊權值都是和v0相關,所有邊權值的起始點都是v0  
  4. *3.大循環1到MG.numVertexes-1次  
  5. *4.遍歷邊權值數組,找當前數組中的最小值,並將終點保存在k中  
  6. *5.打印邊  
  7. *6.將加入的頂點的lowcost設置爲0  
  8. *7.使用新加入的頂點的鄰接矩陣來更新lowcost數組和adjvex數組  
  9. * 
  10. * 
  11. */  
  12. void MiniSpanTree_Prim(MGraph MG){ 
  13.     int min,i,j,k; 
  14.     int adjvex[MAXVEX];//存儲與邊對應的相關起始頂點  
  15.     int lowcost[MAXVEX];//存儲頂點間邊的權值 
  16.     lowcost[0] = 0;//權值爲0表示此小標(V0)的頂點已經加入到了生成樹中  
  17.     adjvex[0] = 0; //初始化第一個頂點的下標爲0 
  18.     for(i=1;i<MG.numVertexes;i++){ 
  19.         lowcost[i] = MG.arc[0][i];//將v0頂點相關的邊的權值存儲數組中 
  20.         adjvex[i] = 0;//這些邊的起點都是v0,所以下標都是0 
  21.     } 
  22.     for(i=1;i<MG.numVertexes;i++){ 
  23.         min = INFINITY;//最小權值初始化爲無窮,通常將infinity設置爲不可能的大數字 
  24.         j=1;k=0; 
  25.         while(j<MG.numVertexes){//在lowcost數組中尋找最小值,並記下最小值的終點存儲在k中  
  26.             if(lowcost[j]!=0 && lowcost[j]<min){ 
  27.                 min = lowcost[j]; 
  28.                 k = j; 
  29.             } 
  30.             j++; 
  31.         } 
  32.         printf("(%d,%d)",adjvex[k],k);//打印邊,起點和終點 
  33.         lowcost[k] = 0;//將當前頂點的權值設置爲0,表示此頂點已經完成任務了 
  34.         for(j=1;j<MG.numVertexes;j++){//更新lowcost數組,使用剛添加進最小生成樹的那個結點的行!  
  35.             if(lowcost[j]!=0 && MG.arc[k][j]<lowcost[j]){//如果下標爲k的頂點各個邊權值小於lowcost的邊權值  
  36.                 lowcost[j] = G.arc[k][j];//更新lowcost數組  
  37.                 adjvex[j] = k;//更新與邊權值相關聯的邊起點信息  
  38.             } 
  39.         }  
  40.     } 
  41. }  
  42. /* 
  43. *1.定義一個邊集,一個結點集,將結點集全部初始化爲0,邊集按照權的大小排列  
  44. *2.循環邊集中的每一條邊,檢查每條邊的起點和終點,如果相同就繼續循環,否則打印並修改parent  
  45. *3.定義一個方法Find來尋找結點的走向  
  46. * 
  47. * 
  48. * 
  49. */  
  50. typedef struct
  51.     int begin; 
  52.     int end; 
  53.     int weight; 
  54. }Edge; 
  55. void MiniSpanTree_Kruskal(MGraph MG,Edge edges[]){//此處使用元素類型爲Edge的邊集數組,已經按照權值由小到大排列  
  56.     int i,n,m; 
  57.     int parent[MAXVEX];//定義一數組用來判斷邊與邊是否形成迴路 
  58.      
  59.     for(i=0;i<MG.numVertexes;i++){//初始化數組爲0  
  60.         parent[i] = 0; 
  61.     } 
  62.     for(i=0;i<MG.numEdges;i++){//循環每一條邊  
  63.         n = Find(parent,edges[i].begin);// 
  64.         m = Find(parent,edges[i].end);// 
  65.         if(n != m){//如果m、n不等說明此邊沒有與現有的生成樹形成環路  
  66.             parent[n] = m;//數組下標記錄了邊起點,數組值記錄了邊終點  
  67.             printf("(%d,%d)%d",edges[i].begin,edges[i].end,edges[i].weight); 
  68.         } 
  69.     } 
  70.  
  71. int Find(int *parent,int f){//查找從f這個座標開始能走到的最遠的結點是哪裏  
  72.     while(parent[f]>0){//如果最後走到的最遠的結點相同,說明是又環路生成的  
  73.         f = parent[f]; 
  74.     } 
  75.     return f; 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章