Prim演算法(一)之 C語言詳解
阿新 • • 發佈:2018-12-30
/* * prim最小生成樹 * * 引數說明: * G -- 鄰接矩陣圖 * start -- 從圖中的第start個元素開始,生成最小樹 */ void prim(Graph G, int start) { int min,i,j,k,m,n,sum; int index=0; // prim最小樹的索引,即prims陣列的索引 char prims[MAX]; // prim最小樹的結果陣列 int weights[MAX]; // 頂點間邊的權值 // prim最小生成樹中第一個數是"圖中第start個頂點",因為是從start開始的。 prims[index++] = G.vexs[start]; // 初始化"頂點的權值陣列", // 將每個頂點的權值初始化為"第start個頂點"到"該頂點"的權值。 for (i = 0; i < G.vexnum; i++ ) weights[i] = G.matrix[start][i]; // 將第start個頂點的權值初始化為0。 // 可以理解為"第start個頂點到它自身的距離為0"。 weights[start] = 0; for (i = 0; i < G.vexnum; i++) { // 由於從start開始的,因此不需要再對第start個頂點進行處理。 if(start == i) continue; j = 0; k = 0; min = INF; // 在未被加入到最小生成樹的頂點中,找出權值最小的頂點。 while (j < G.vexnum) { // 若weights[j]=0,意味著"第j個節點已經被排序過"(或者說已經加入了最小生成樹中)。 if (weights[j] != 0 && weights[j] < min) { min = weights[j]; k = j; } j++; } // 經過上面的處理後,在未被加入到最小生成樹的頂點中,權值最小的頂點是第k個頂點。 // 將第k個頂點加入到最小生成樹的結果陣列中 prims[index++] = G.vexs[k]; // 將"第k個頂點的權值"標記為0,意味著第k個頂點已經排序過了(或者說已經加入了最小樹結果中)。 weights[k] = 0; // 當第k個頂點被加入到最小生成樹的結果陣列中之後,更新其它頂點的權值。 for (j = 0 ; j < G.vexnum; j++) { // 當第j個節點沒有被處理,並且需要更新時才被更新。 if (weights[j] != 0 && G.matrix[k][j] < weights[j]) weights[j] = G.matrix[k][j]; } } // 計算最小生成樹的權值 sum = 0; for (i = 1; i < index; i++) { min = INF; // 獲取prims[i]在G中的位置 n = get_position(G, prims[i]); // 在vexs[0...i]中,找出到j的權值最小的頂點。 for (j = 0; j < i; j++) { m = get_position(G, prims[j]); if (G.matrix[m][n]<min) min = G.matrix[m][n]; } sum += min; } // 列印最小生成樹 printf("PRIM(%c)=%d: ", G.vexs[start], sum); for (i = 0; i < index; i++) printf("%c ", prims[i]); printf("\n"); }