普里姆算法的基本思想如下:
假设N={V,{E}}是连通网,TE是N上最小生成树中边的集合。从U={u}开始,TE={}开始,重复执行下述操作:在所有的u属于U,v属于V-U的边(u,v)的边中找到权值最小的一条边,并且并入TE,同时u并入U,直到U=V;
先设一个辅助数组closedge[MAX],初始时先把第一个结点存入closedge[i].adjvex,令closedge数组中adjvex的初始值全部为v1结点,并把权值存入closedge[i].lowcost中,
每次执行算法时,从U-V中选取权值最小的一条边,并入TE。
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef int AdjMatrix[MAX][MAX];
typedef struct{
char vexs[MAX];
int vexnum,arcnum;
AdjMatrix arcs;
}MGraph;
typedef struct{
int lowcost;
char adjvex;
}closedge[MAX];
typedef struct{
closedge close;
}Edge;
int LocateAdj(MGraph &G, char v){
int i;
for(i = 0; i < G.vexnum; i ++){
if(G.vexs[i] == v)
return i;
}
return -1;
}
void CreateMGraph(MGraph &G){
int i,j,k,cost;
char v1,v2;
scanf("%d%d",&G.vexnum,&G.arcnum);
getchar();
for(i = 0; i < G.vexnum; i ++){
scanf("%c",&G.vexs[i]);
}
for(i = 0; i < G.vexnum; i ++){
for(j = 0; j < G.vexnum; j ++){
G.arcs[i][j] = 65537;
}
}
for(k = 0; k < G.arcnum; k ++){
getchar();
scanf("%c%c",&v1,&v2);
scanf("%d",&cost);
i = LocateAdj(G,v1); j = LocateAdj(G,v2);
G.arcs[i][j] = G.arcs[j][i] = cost;
}
}
void PRIM(MGraph G, int k){
int i,j;
Edge E;
for(i = 0; i < G.vexnum; i ++){
if(i != k){
E.close[i].adjvex = G.vexs[k];
E.close[i].lowcost = G.arcs[k][i];
}
}
E.close[k].lowcost = 0;
for(i = 1; i < G.vexnum; i ++){
int MinCost = 65537;
for(j = 0; j < G.vexnum; j ++){
if(E.close[j].lowcost < MinCost && E.close[j].lowcost){
k = j;
MinCost = E.close[j].lowcost;
}
}
printf("(%c,%c)\n",E.close[k].adjvex,G.vexs[k]);
E.close[k].lowcost = 0;
for(j = 0; j < G.vexnum; j ++){
if(G.arcs[k][j] < E.close[j].lowcost){
E.close[j].adjvex = G.vexs[k];
E.close[j].lowcost = G.arcs[k][j];
}
}
}
}
int main(){
MGraph G;
CreateMGraph(G);
PRIM(G,0);
return 0;
}