标签:
//普里姆算法 //构造连通网的最小代价生成树 /* 基本思路: 1. 任选一个结点,任选一个作为这棵树的起点。 2. 找出所有与当前树中叶子结点连接的边,找出权最小的一条边, 将这条边的另一个端点加入到树中。 3. 重复2的操作,直到连接所有结点。 重点: 1.lowcost数组里保存的是与“当前树中所有叶子节点”有连线的未加入树的结点 2.adjvex数组:体会函数中的“printf("(%d, %d)\n", adjvex[k], k);” */ #include <stdio.h> #define MAXNUM 9 //顶点的最大数量 #define INFINITY 65535 typedef struct { char vexs[MAXNUM]; //包含所有顶点的数组 int arc [MAXNUM][MAXNUM]; //邻接矩阵 int numVertexes, numEdges; //当前图中的顶点数量和边的数量 } Graph; //建立无向图的邻接矩阵 void CreatGraph(Graph* G) { int i, j; /* printf("请输入顶点数和边数"); scanf("%d", &G->numVertexes); scanf("%d", &G->numEdges); for (i = 0; i < G->numVertexes; i++) for (j = 0; j < G->numVertexes; j++) G->arc[i][j] = INFINITY; for (k = 0; k < G->numEdges; k++) { printf("请输入边在邻接矩阵中的横纵坐标和权值:"); fflush(stdin); scanf("%d", &i); scanf("%d", &j); scanf("%d", &w); G->arc[i][j] = w; G->arc[j][i] = G->arc[i][j]; } */ G->numVertexes = 9; G->numEdges = 15; for (i = 0; i < G->numVertexes; i++) for (j = 0; j < G->numVertexes; j++) { if (i == j) G->arc[i][j]=0; else G->arc[i][j] = INFINITY; } G->arc[0][1]=10; G->arc[0][5]=11; G->arc[1][2]=18; G->arc[1][8]=12; G->arc[1][6]=16; G->arc[2][8]=8; G->arc[2][3]=22; G->arc[3][8]=21; G->arc[3][6]=24; G->arc[3][7]=16; G->arc[3][4]=20; G->arc[4][7]=7; G->arc[4][5]=26; G->arc[5][6]=17; G->arc[6][7]=19; for(i = 0; i < G->numVertexes; i++) { for(j = i; j < G->numVertexes; j++) { G->arc[j][i] =G->arc[i][j]; } } printf("\n该邻接矩阵是\n"); for (i = 0; i < G->numVertexes; i++) { for (j = 0; j < G->numVertexes; j++) printf("%5d ", G->arc[i][j]); printf("\n"); } } //普里姆算法生成最小生成树 void MiniSpanTree_Prim(Graph G) { int min, i, j, k; int lowcost[MAXNUM];//保存相关顶点之间边的权值 int adjvex[MAXNUM];//保存相关顶点下标 lowcost[0] = 0; adjvex[0] = 0;//第一个顶点下标为0 for (i = 1; i < G.numVertexes; i++) {//循环搜索除下标0外的全部顶点 lowcost[i] = G.arc[0][i];//将与V0顶点有关的顶点的边的权值存入数组 adjvex[i] = 0;//全部初始化为0的下标 } for (i = 1; i < G.numVertexes; i++) { min = INFINITY;//将最小值初始化为“无限大” j = 1; k = 0; //这个while循环最终找到的是与当前叶节点距离最近的顶点的下标值(存入k) while (j < G.numVertexes) { if (lowcost[j]!=0 && lowcost[j]<min) { min = lowcost[j]; k = j; } j++; } //在最小生成树中,adjvex[k]节点为k节点的父节点 printf("(%d, %d)\n", adjvex[k], k); lowcost[k] = 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; //注意:意思是新加入候选节点的j节点(们)是当前加入树的k节点的孩子节点 } } } } int main() { Graph G; CreatGraph(&G); MiniSpanTree_Prim(G); return 0; }
标签:
原文地址:http://www.cnblogs.com/qianbixin/p/4998347.html