Prim算法求最小生成树
Prim算法求图的最小生成树(使用的图的数据结构是图的邻接矩阵存储表示)
/* minCost数组:该数组是结构数组,即每个元素是一个结构类型。该结构有两个域:lowCost用来保存所有已经在
*最小生成树中的顶点,到所有还没有在最小生成树中的顶点的所有权值中的最小的;vertax域用
* 来保存是哪个在最小生成树中的顶点拥有着这个最小的权值。并且这个数组的下标隐含着顶点的
* 信息。例如,第2个数组元素在程序运行中的某一个时刻表示:已经形成的MST中的vertax顶点到
* 图中的第2个顶点的权值为lowCost,并且是树内顶点和数外顶点链接的最小的权值。
* 所以这个数组要不断的更新。
* 假设整个生成树的过程从顶点a开始,那么这个数组的初始元素为该图的邻接矩阵中顶点a的一行
* (该行表示的是a于其他的顶点的权值),并且将数组的vertax都设置为a。表示从MST中的顶点a到
* 数外的所有顶点的权值,然后从该数组中选出lowCost最小的值。为生成树的第二个顶点。
* 现在树中有两个顶点,所以需要比较是哪个顶点和数外的其他顶点的权值比较小,minCost数组
* 中的信息是树中顶点到其他顶点的最小权值,所以和将要加入的新的顶点的邻接矩阵中的一行(
* 存放的是该顶点与所有其他的顶点的权值)
* 进行比较即可,小的就更新。
* */
1 #include<stdio.h> 2 3 #define MAX_VERTAX_SIZE 20 4 #define INFINITE 65535 5 #define OK 1 6 #define ERROR 0 7 8 //图的邻接矩阵表示的结构定义 9 typedef int Status; 10 typedef char VertaxElemType; 11 typedef struct GraphAM{ 12 VertaxElemType VertaxArray[MAX_VERTAX_SIZE]; 13 int AdjacencyMatrix[MAX_VERTAX_SIZE][MAX_VERTAX_SIZE]; 14 int vertaxNum; 15 int eageNum; 16 }GraphAM; 17 18 //用于Prim算法的辅助结构: 19 typedef struct MinCostEage{ 20 VertaxElemType vertax; 21 int lowCost; 22 }MinCostEage; 23 24 int LocateVertax(GraphAM G, VertaxElemType c){ 25 int i; 26 for( i = 0; i < G.vertaxNum; i++ ){ 27 if( c == G.VertaxArray[i] ) 28 return i; 29 } 30 return -1; 31 } 32 Status CreateUDG(GraphAM* G){ 33 int i,j,index_v,index_w, weight; 34 VertaxElemType v,w; 35 printf(" Greate UndiGraph with Cost\n"); 36 printf("Please enter the number of Vertax and Eage:"); 37 scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum)); 38 39 printf("ok, please enter the value of the vertaxes:\n"); 40 for( i = 0; i < G->vertaxNum; i++ ){ 41 scanf("%c%*c", &(G->VertaxArray[i])); 42 } 43 for( i = 0; i < G->vertaxNum; i++ ) 44 for( j = 0; j < G->vertaxNum; j++ ) 45 G->AdjacencyMatrix[i][j] = INFINITE; 46 for( i = 0; i < G->eageNum; i++ ){ 47 printf("ok,please enter the two Vertax and Wight of eage %d,\nNote:Seperated by Space: ", i+1); 48 scanf("%c %c %d%*c", &v, &w, &weight); 49 if( LocateVertax(*G, v) != -1 ) 50 index_v = LocateVertax(*G, v); 51 else 52 return ERROR; 53 if( LocateVertax(*G, w) != -1 ) 54 index_w = LocateVertax(*G, w); 55 else 56 return ERROR; 57 G->AdjacencyMatrix[index_v][index_w] = G->AdjacencyMatrix[index_w][index_v] = weight; 58 } 59 return OK; 60 } 61 void PrintAdjacencyMatrix(GraphAM G){ 62 printf("Show the Adjacency Matrix of Graph('#' repersents infinite)\n"); 63 int i,j; 64 for( i = 0; i < G.vertaxNum; i++ ){ 65 for( j = 0; j< G.vertaxNum; j++ ){ 66 if( G.AdjacencyMatrix[i][j] != INFINITE ) 67 printf("%5d", G.AdjacencyMatrix[i][j]); 68 else 69 printf(" #"); 70 } 71 printf("\n\n"); 72 } 73 } 74 //求图G的最小生成树,从顶点v开始 75 Status Prim(GraphAM G, VertaxElemType v){ 76 int i,index_v,min,min_index,j; 77 index_v = LocateVertax(G, v); 78 MinCostEage minCost[MAX_VERTAX_SIZE]; //数组的下标隐含是第几个顶点 79 for( i = 0; i < G.vertaxNum; i++ ){ 80 minCost[i].lowCost = G.AdjacencyMatrix[index_v][i]; //初始化数组为起始顶点的AdjacencyMatrix[起始顶点]信息 81 minCost[i].vertax = v; //MST中的哪个顶点与数外有本数组元素中的lowCost值 82 } 83 minCost[index_v].lowCost = 0; //已经在MST中的标志,使得没有机会参加数组中lowCost的选取 84 printf("MST(Minimum Cost Spinning Tree):\n"); 85 for( i = 1; i < G.vertaxNum; i++ ){ 86 for( j = 0; j < G.vertaxNum; j++ ){ //找第一个非0的作为min,为了避免第一个是0 87 if( minCost[j].lowCost != 0 ){ 88 min = minCost[j].lowCost; 89 min_index = j; 90 break; 91 } 92 } 93 for( j = 0; j < G.vertaxNum; j++ ){ //寻找该数组中的当前的最小权值 94 if( minCost[j].lowCost > 0 && minCost[j].lowCost < min ){ 95 min = minCost[j].lowCost; 96 min_index = j; 97 } 98 } 99 printf("(%c, %c)\t", minCost[min_index].vertax, G.VertaxArray[min_index]);//数组的下标存储了第二个%c的需要的信息, 100 //vertax域提供了第一个%c需要的信息 101 minCost[min_index].lowCost = 0; 102 for( j = 0; j < G.vertaxNum; j++ ){ 103 if( G.AdjacencyMatrix[min_index][j] < minCost[j].lowCost ){ 104 minCost[j].lowCost = G.AdjacencyMatrix[min_index][j]; 105 minCost[j].vertax = G.VertaxArray[min_index]; 106 } 107 } 108 } 109 } 110 111 int main(){ 112 GraphAM G; 113 CreateUDG(&G); 114 PrintAdjacencyMatrix(G); 115 Prim(G, 'a'); 116 return 0; 117 }