#include <stdio.h>
#include <stdlib.h>
#define PeakMax 20 //最大顶点数为20
#define MaxInt 32767 //表示 ∞
typedef char PeakType;
typedef struct//邻接矩阵结构体
{
PeakType Peak[PeakMax];//顶点元素
int ADJ[PeakMax][PeakMax];//邻接矩阵
int peaknum,sidenum;//图的顶点和边的数目
}MG;
typedef struct//辅助数组结构体(候选最短边)
{
PeakType adjpeak;//最短边的邻接点
int lowcost;//最短边的权值
}ShortEdge;
int LocatMark(MG *G,PeakType v)//查找元素v的下标,并返回下标
{
int i;
for(i=0;i<G->peaknum;i++)
{
if(v==G->Peak[i])
{
return i;
}
}
printf("没有此顶点!\n");
return -1;
}
void CreateUndig(MG *G)//构建无向网
{
int i,j;
printf("请输入顶点个数和边条数:\n");
printf("顶点数为:");
scanf("%d",&G->peaknum);
printf("边 数为:");
scanf("%d",&G->sidenum);
printf("\n");
printf("\n");
printf("请输入顶点名称(不用空格隔开):");
scanf("%s",G->Peak);
printf("\n");
for(i=0;i<G->peaknum;i++)
for(j=0;j<G->peaknum;j++)
{
G->ADJ[i][j]=MaxInt;
}
int n,m;
PeakType v1,v2;
int w;
printf("请输入边的名称和权值(例:AB,15):\n");
for(i=0;i<G->sidenum;i++)
{
printf("输入第%d条边名称和权值:",i+1);
scanf(" %c%c,%d",&v1,&v2,&w);
n=LocatMark(G,v1);
m=LocatMark(G,v2);
if(n==-1||m==-1)
{
printf("没有此顶点!\n");
return;
}
G->ADJ[n][m]=w;
G->ADJ[m][n]=w;
}
}
void PrintADJ(MG G)
{
int i,j;
printf("\n-------------------------------");
printf("\n 邻接矩阵如下:\n\n");
printf("\t ");
for(i=0;i<G.peaknum;i++)
printf("\t%c",G.Peak[i]);
printf("\n");
for(i=0;i<G.peaknum;i++)
{
printf("\t%c",G.Peak[i]);
for(j=0;j<G.peaknum;j++)
{
if(G.ADJ[i][j]==MaxInt)
printf("\t∞");
else printf("\t%d",G.ADJ[i][j]);
}
printf("\n");
}
}
int minimal(MG *G,ShortEdge *shortedge)
{
int i,j;
int min,loc;
min=MaxInt;
for(i=1;i<G->peaknum;i++)
{
if(min>shortedge[i].lowcost&&shortedge[i].lowcost!=0)
{
min=shortedge[i].lowcost;
loc=i;
}
}
return loc;
}
void MiniSpanTree_Prim(MG *G,PeakType start)
{
int i,j,k;
ShortEdge shortedge[PeakMax];
k=LocatMark(G,start);
for(i=0;i<G->peaknum;i++)
{
shortedge[i].adjpeak=start;
shortedge[i].lowcost=G->ADJ[k][i];
}
shortedge[k].lowcost=0;
for(i=0;i<G->peaknum-1;i++)
{
k=minimal(G,shortedge);
printf("%c->%c,%d\n",shortedge[k].adjpeak,G->Peak[k],shortedge[k].lowcost);
shortedge[k].lowcost=0;
for(j=0;j<G->peaknum;j++)
{
if(G->ADJ[k][j]<shortedge[j].lowcost)
{
shortedge[j].lowcost=G->ADJ[k][j];
shortedge[j].adjpeak=G->Peak[k];
}
}
}
}
int main()
{
PeakType start;
MG G;
CreateUndig(&G);
PrintADJ(G);
printf("请输入起始点为:");
scanf(" %c",&start);
printf("最小生成树为:\n");
MiniSpanTree_Prim(&G,start);
return 0;
}
贪心策略-最小生成树Prim算法
最新推荐文章于 2024-08-14 23:48:25 发布