Prim算法求最小生成树使用的图的存储结构是图的邻接矩阵
#include<stdio.h>
#define MAX_VERTAX_SIZE 20
#define INFINITE 65535
#define OK 1
#define ERROR 0
//图的邻接矩阵表示的结构定义
typedef int Status;
typedef char VertaxElemType;
typedef struct GraphAM{
VertaxElemType VertaxArray[MAX_VERTAX_SIZE];
int AdjacencyMatrix[MAX_VERTAX_SIZE][MAX_VERTAX_SIZE];
int vertaxNum;
int eageNum;
}GraphAM;
//用于Prim算法的辅助结构:
typedef struct MinCostEage{
VertaxElemType vertax;
int lowCost;
}MinCostEage;
int LocateVertax(GraphAM G, VertaxElemType c){
int i;
for( i = 0; i < G.vertaxNum; i++ ){
if( c == G.VertaxArray[i] )
return i;
}
return -1;
}
Status CreateUDG(GraphAM* G){
int i,j,index_v,index_w, weight;
VertaxElemType v,w;
printf(" Greate UndiGraph with Cost\n");
printf("Please enter the number of Vertax and Eage:");
scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));
printf("ok, please enter the value of the vertaxes:\n");
for( i = 0; i < G->vertaxNum; i++ ){
scanf("%c%*c", &(G->VertaxArray[i]));
}
for( i = 0; i < G->vertaxNum; i++ )
for( j = 0; j < G->vertaxNum; j++ )
G->AdjacencyMatrix[i][j] = INFINITE;
for( i = 0; i < G->eageNum; i++ ){
printf("ok,please enter the two Vertax and Wight of eage %d,\nNote:Seperated by Space: ", i+1);
scanf("%c %c %d%*c", &v, &w, &weight);
if( LocateVertax(*G, v) != -1 )
index_v = LocateVertax(*G, v);
else
return ERROR;
if( LocateVertax(*G, w) != -1 )
index_w = LocateVertax(*G, w);
else
return ERROR;
G->AdjacencyMatrix[index_v][index_w] = G->AdjacencyMatrix[index_w][index_v] = weight;
}
return OK;
}
void PrintAdjacencyMatrix(GraphAM G){
printf("Show the Adjacency Matrix of Graph('#' repersents infinite)\n");
int i,j;
for( i = 0; i < G.vertaxNum; i++ ){
for( j = 0; j< G.vertaxNum; j++ ){
if( G.AdjacencyMatrix[i][j] != INFINITE )
printf("%5d", G.AdjacencyMatrix[i][j]);
else
printf(" #");
}
printf("\n\n");
}
}
//求图G的最小生成树,从顶点v开始
Status Prim(GraphAM G, VertaxElemType v){
int i,index_v,min,min_index,j;
index_v = LocateVertax(G, v);
MinCostEage minCost[MAX_VERTAX_SIZE]; //数组的下标隐含是第几个顶点
for( i = 0; i < G.vertaxNum; i++ ){
minCost[i].lowCost = G.AdjacencyMatrix[index_v][i]; //初始化数组为起始顶点的AdjacencyMatrix[起始顶点]信息
minCost[i].vertax = v; //MST中的哪个顶点与数外有本数组元素中的lowCost值
}
minCost[index_v].lowCost = 0; //已经在MST中的标志,使得没有机会参加数组中lowCost的选取
printf("MST(Minimum Cost Spinning Tree):\n");
for( i = 1; i < G.vertaxNum; i++ ){
for( j = 0; j < G.vertaxNum; j++ ){ //找第一个非0的作为min,为了避免第一个是0
if( minCost[j].lowCost != 0 ){
min = minCost[j].lowCost;
min_index = j;
break;
}
}
for( j = 0; j < G.vertaxNum; j++ ){ //寻找该数组中的当前的最小权值
if( minCost[j].lowCost > 0 && minCost[j].lowCost < min ){
min = minCost[j].lowCost;
min_index = j;
}
}
printf("(%c, %c)\t", minCost[min_index].vertax, G.VertaxArray[min_index]);//数组的下标存储了第二个%c的需要的信息,
//vertax域提供了第一个%c需要的信息
minCost[min_index].lowCost = 0;
for( j = 0; j < G.vertaxNum; j++ ){
if( G.AdjacencyMatrix[min_index][j] < minCost[j].lowCost ){
minCost[j].lowCost = G.AdjacencyMatrix[min_index][j];
minCost[j].vertax = G.VertaxArray[min_index];
}
}
}
}
/* minCost数组:该数组是结构数组,即每个元素是一个结构类型。该结构有两个域:lowCost用来保存所有已经在
* 最小生成树中的顶点,到所有还没有在最小生成树中的顶点的所有权值中的最小的;vertax域用
* 来保存是哪个在最小生成树中的顶点拥有着这个最小的权值。并且这个数组的下标隐含着顶点的
* 信息。例如,第2个数组元素在程序运行中的某一个时刻表示:已经形成的MST中的vertax顶点到
* 图中的第2个顶点的权值为lowCost,并且是树内顶点和数外顶点链接的最小的权值。
* 所以这个数组要不断的更新。
* 假设整个生成树的过程从顶点a开始,那么这个数组的初始元素为该图的邻接矩阵中顶点a的一行
* (该行表示的是a于其他的顶点的权值),并且将数组的vertax都设置为a。表示从MST中的顶点a到
* 数外的所有顶点的权值,然后从该数组中选出lowCost最小的值。为生成树的第二个顶点。
* 现在树中有两个顶点,所以需要比较是哪个顶点和数外的其他顶点的权值比较小,minCost数组
* 中的信息是树中顶点到其他顶点的最小权值,所以和将要加入的新的顶点的邻接矩阵中的一行(
* 存放的是该顶点与所有其他的顶点的权值)
* 进行比较即可,小的就更新。
* */
int main(){
GraphAM G;
CreateUDG(&G);
PrintAdjacencyMatrix(G);
Prim(G, 'a');
return 0;
}