1. 程式人生 > >最小生成樹圖文詳解(Prim演算法)

最小生成樹圖文詳解(Prim演算法)

最小生成樹 就像幾個村莊都不相通, 要修路, 怎麼修, 這個花的錢最少, 這種最優選擇就是最小生成樹
設G = (V, E)是無向連通圖(V是結點集, E是邊集),相對於村莊例子,V就是那些村莊的集合,E就是村莊之間路的集合 設T = (U, TE)是最小生成樹, U是結點集,TE是邊集 Prim演算法的思想
  • 首先在V集合中任意選擇一個村莊作為起始點i,將i點併入U集合中,然後在找一個修路到i村莊最便宜的j村莊併入集合TE中(在所有i∈U, j∈V-U中找一條代價最小的邊(i,j) 
  • 重複第一步的操作

設陣列adjvex[n]表示候選最短邊的領接點 設陣列lowcast[n]表示權值 其值如下,含義是候選最短邊(i,j)的權值為w,其中iV-U , j∈U adjvex[i] = j lowcost[i] = w
介紹了這麼多抽象概念,還是看圖理解一下Prim演算法的流程


C語言實現

#include<stdio.h>
#define MaxSize 100
struct MGraph {
  int vertex[MaxSize];// 定義存放頂點的一維陣列
  int edge[MaxSize][MaxSize]; // 存放邊的二維陣列
  int vertexNum, edgeNum; 
};
int MinEdge(int   *lowcost, int num) {
  int min = 9999;
  int index = -1;
  for(int i = 0; i < num; i++) {
    if(lowcost[i] < min && lowcost[i] != 0) {
      min = lowcost[i];
      index = i;
    }
  }
  return index;
}
void Prim(MGraph *G, int v) {// 從頂點V出發 
  int i, j, k;
  int adjvex[MaxSize], lowcost[MaxSize];
  for (i = 0; i < G -> vertexNum; i++) {// 初始化 
    lowcost[i] = G -> edge[v][i];
    adjvex[i] = v;
  }
  lowcost[v] = 0; /* 將頂點v加入集合*/
  for (k = 1; k < G -> vertexNum; k++) {
    j = MinEdge(lowcost, G -> vertexNum);// 尋找最短邊的領接點
    printf("(%d, %d)%d ", j, adjvex[j], lowcost[j]);// 輸出最短邊(j, i)及其權值 
    lowcost[j] = 0; /* 將頂點j加入集合*/
    for (i = 0; i < G ->vertexNum; i++) { /* 更新 */
      if (G -> edge[i][j] < lowcost[i]) {
        lowcost[i] = G -> edge[i][j];
        adjvex[i] = j;
      } 
    }
  }
}

int main() {
  MGraph g;
  MGraph *G = &g;
  G -> vertexNum = 6;//6個頂點
  G -> edgeNum = 9;// 9條邊
  for(int i = 0; i < 6; i++)
    for(int j = 0; j < 6; j++)
      G -> edge[i][j] = 9999;// 無限大 
  G -> edge[0][1] = 34;  G -> edge[1][0] = 34;
  G -> edge[0][2] = 46;  G -> edge[2][0] = 46;
  G -> edge[0][5] = 19;  G -> edge[5][0] = 19;
  G -> edge[1][4] = 12;  G -> edge[4][1] = 12;
  G -> edge[2][3] = 17;  G -> edge[3][2] = 17;
  G -> edge[2][5] = 25;  G -> edge[5][2] = 25;
  G -> edge[3][4] = 38;  G -> edge[4][3] = 38;
  G -> edge[3][5] = 25;  G -> edge[5][3] = 25;
  G -> edge[4][5] = 26;  G -> edge[5][4] = 26;
  Prim(G, 0);
}







參考書籍:資料結構(王紅德 皮德常)