先看一下下面這張圖。
算法思想:可取圖中任意一個頂點V作為生成樹的根,之后若要往生成樹上添加頂點W,則在頂點V和W之間必定存在一條邊。並且該邊的權值在所有連通頂點V和W之間的邊中取值最小。
一般情況下,假設n個頂點分成兩個集合:U(包含已落在生成樹上的結點)和V-U(尚未落在生成樹上的頂點),則在所有連通U中頂點和V-U中頂點的邊中選取權值最小的邊
下面是其C語言算法實現:
//最小生成樹 普里姆算法 采用鄰接矩陣存儲 void MiniSpanTree(MGraph *G) { int min, i, j, k; int adjvex[MaxVex]; //保存相關頂點下標 int lowcost[MaxVex]; //保存相關頂點間邊的權值 lowcost[0] = 0; //初始化第一個權值為0,即V0加入生成樹 adjvex[0] = 0; //初始化第一個頂點下標為0 //初始化操作 for (i=1; i<G->numVertexes; ++i) { lowcost[i] = G->arc[0][i]; adjvex[i] = 0; //將v0頂點與之有邊的權值存入數組 並初始化都為v0的下標 } //adjvex[i],i是其他節點的標記,adjvex[i]=0即是把0~n的節點都與節點0關聯起來 for (i=1; i<G->numVertexes; ++i) { min = INFINITY; j = 1; k = 0; //保存權值最小的頂點 //遍歷v-u集合中剩下的節點 while (j<G->numVertexes) { //如果兩個頂點之間存在邊並且權值小於min if (lowcost[j]!=0 && lowcost[j]<min) { min = lowcost[j]; k = j; } ++j; } printf("(%d, %d)", adjvex[k], k); //輸出當前頂點邊中權值最小的邊 lowcost[k] = 0; //將當前頂點的權值設為0,表示此頂點已經完成任務 //更新新節點與其他節點之間的最小花費和關聯 for (j=1; j<G->numVertexes; ++j) { if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j]) { lowcost[j] = G->arc[k][j]; adjvex[j] = k; } } } }