/* * Prim最小生成树C代码,时间复杂度O(n*n),适用于边稠密图 */ #include <stdio.h> #define INFINITY 2147483647 //最大值 #define MAX_VERTEX_NUM 20 //最大顶点个数 #define ERROR -1 typedef int VRType; typedef int VertexType;//顶点名称类型 typedef struct { VRType adj; //VRType是顶点关系类型。对无权图,用1或0表示相邻否; //对带权图,则为权值类型。 //此处可添加弧相关信息 }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { VertexType vexs[MAX_VERTEX_NUM]; //顶点向量 AdjMatrix arcs;//邻接矩阵 int vexnum, arcnum; //此处可添加图种类标志 }MGraph; struct { VertexType adjvex; VRType lowcost; }closeedge[MAX_VERTEX_NUM]; int LocateVex(MGraph G, VertexType v); MGraph CreatUDN(MGraph G); void PrintUDN(MGraph G); void MiniSpanTree_PRIM(MGraph G, VertexType u); int main(void) { MGraph G; VertexType u = 1; G = CreatUDN(G); MiniSpanTree_PRIM(G,u); return 0; } /*查找v在图G中的位置*/ int LocateVex(MGraph G, VertexType v) { int i; for (i=0; i<G.vexnum; i++) { if (v==G.vexs[i]) { return i; } } return ERROR; } /*构造邻接矩阵存储的无向网*/ MGraph CreatUDN(MGraph G) { int i, j, k, w; VertexType v1, v2;//存放每次输入的边 printf("Input vexnum, arcnum:"); scanf("%d %d", &G.vexnum, &G.arcnum); for (i=0; i<G.vexnum; i++)//初始化邻接矩阵 { for (j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = INFINITY; } } printf("Name the vertexes./n"); for (k = 0; k<G.vexnum; k++) { printf("NO.%d ", k+1); scanf("%d", &G.vexs[k]); } printf("/nInput the arc v1->v2 and weight/n"); for (k = 0; k<G.arcnum; k++) { printf("arc%d->", k+1); scanf("%d %d %d",&v1, &v2, &w); i = LocateVex(G, v1); j = LocateVex(G, v2); if (ERROR==i || ERROR==j) { printf("Hadn't find it!/n"); printf("arc%d->", k+1); scanf("%d %d %d",&v1, &v2, &w); i = LocateVex(G, v1); j = LocateVex(G, v1); } G.arcs[i][j].adj = w; G.arcs[j][i].adj = G.arcs[i][j].adj;//无向图邻接矩阵对角线对称 } return G; } /*二维数组形式输出邻接矩阵*/ void PrintUDN(MGraph G) { int i, j; for (i=0; i<G.vexnum; i++) { printf("%d: ", G.vexs[i]); for (j=0; j<G.vexnum; j++) { printf("%d", G.arcs[i][j].adj); } printf("/n"); } } /*普里姆最小生成树*/ void MiniSpanTree_PRIM(MGraph G, VertexType u) { int i, j, k, t; VRType min; k = LocateVex(G, u); for (j=0; j<G.vexnum; j++) //辅助数组初始化 { if (j!=k) { closeedge[j].adjvex = u; closeedge[j].lowcost = G.arcs[k][j].adj; } } closeedge[k].lowcost = 0; printf("The MiniSpanTree arcs are:"); for (i=1; i<G.vexnum; i++) { j = 0; while (!closeedge[j].lowcost) { j++; } min = closeedge[j].lowcost; k = j; for (t=j+1; t<G.vexnum; t++) { if (closeedge[t].lowcost>0) { if (closeedge[t].lowcost < min) { min = closeedge[t].lowcost; k = t; } } } closeedge[k].lowcost = 0; printf(" <%d, %d> ", closeedge[k].adjvex, G.vexs[k]); for (j=0; j<G.vexnum; j++) { if (G.arcs[k][j].adj < closeedge[j].lowcost)//新顶点并入U后重新选择最小边 { closeedge[j].adjvex = G.vexs[k]; closeedge[j].lowcost = G.arcs[k][j].adj; } } } }