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 }

posted @ 2016-03-13 14:48  robin_X  阅读(5376)  评论(0编辑  收藏  举报