#include<stdio.h>
#include<stdlib.h>
#define MAXV 50
#define INF 32767 //表示∞
typedef char VertexType; //顶点的数据类型
typedef int EdgeType; //带权图中边上权值的数据类型
typedef struct {
VertexType Vex[MAXV]; //顶点表
EdgeType edges[MAXV][MAXV]; //邻接矩阵,边表
int n, e; //图的当前顶点数和边数
}MGraph; //基于邻接矩阵法的带权无向图
typedef struct
{
int u; //边的起始顶点
int v; //边的终止顶点
int w; //边的权值
}Edge;
void CreateMGraph(MGraph *G)
{
int i,j,k,w;
printf("请输入顶点数和边数,用空格隔开:\n");
scanf("%d %d",&G->n,&G->e);
fflush(stdin);
printf("请依次输入顶点的值:\n");
for(int i = 0;i < G->n; i++)
{
printf("输入第%d个顶点信息:\n",i+1);
scanf("%c",&G->Vex[i]);
fflush(stdin);
}
for(i = 0;i < G->n; i++)
for(j = 0;j <G->n; j++)
G->edges[i][j] = INF;
printf("输入边<vi,vj>的下标i,下标j和权w:\n");
for (k = 0; k < G->e; k++)
{
scanf("%d %d %d", &i, &j, &w); //输入边<vi,vj>上的权值w
G->edges[i][j] = w;
G->edges[j][i] = G->edges[i][j]; //无向图矩阵是对称的
}
}
void CreateMGraph2(MGraph *G)
{
int i,j,k,w;
printf("请输入顶点数和边数,用空格隔开:\n");
scanf("%d %d",&G->n,&G->e);
fflush(stdin);
printf("请依次输入顶点的值:\n");
for(int i = 0;i < G->n; i++)
{
printf("输入第%d个顶点信息:\n",i+1);
scanf("%c",&G->Vex[i]);
fflush(stdin);
}
for(i = 0;i < G->n; i++)
for(j = 0;j <G->n; j++)
G->edges[i][j] = INF;
printf("输入边<vi,vj>的下标i,下标j和权w:\n");
for (k = 0; k < G->e; k++)
{
scanf("%d%d%d", &i, &j, &w);
G->edges[i][j] = w;
}
}
void PrintMatrix(MGraph G)
{
int i,j;
printf("邻接矩阵表示如下:\n");
for (i = 0; i < G.n; i++)
{
for (j = 0; j < G.n; j++)
printf("%-10d", G.edges[i][j]);
printf("\n");
}
}
void PrintVex(MGraph g)
{
printf("\n顶点集合为:");
for(int i=0;i<g.n;i++)
printf("%c ",g.Vex[i]);
printf("\n");
}
void Prim(MGraph g,int v)
{
int lowcost[MAXV];
int min;
int closest[MAXV],i,j,k;
printf("普里姆算法:\n");
for(i=0;i<g.n;i++)
{
lowcost[i]=g.edges[v][i];
closest[i]=v;
}
lowcost[v]=0;
for(i=1;i<g.n;i++)
{
min=INF;
for(j=0;j<g.n;j++)
if(lowcost[j]!=0&&lowcost[j]<min)
{
min=lowcost[j];
k=j;
}
printf("边(%d,%d)权为:%d\n",closest[k],k,min);
lowcost[k]=0;
for(j=0;j<g.n;j++)
if(g.edges[k][j]<lowcost[j])
{
lowcost[j]=g.edges[k][j];
closest[j]=k;
}
}
}
void InsertSort(Edge r[],int n)
{
int i,j;
for(i=2;i<n;i++)
{
if(r[i].w<r[i-1].w)
{
r[0]=r[i];
j=i-1;
while(r[0].w<r[j].w&&j>=1)
{
r[j+1]=r[j];
j=j-1;
}
r[j+1]=r[0];
}
}
}
void Kruskal(MGraph g)
{
int i,j,u1,v1,sn1,sn2,k;
int vset[MAXV];
Edge E[MAXV];
k=0;
printf("克鲁斯卡尔算法:\n");
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++)
if(g.edges[i][j]!=0&&g.edges[i][j]!=INF)
{
E[k].u=i;
E[k].v=j;
E[k].w=g.edges[i][j];
k++;
}
InsertSort(E,g.e);
for(i=0;i<g.n;i++)
vset[i]=i;
k=1;
j=0;
while(k<g.n)
{
u1=E[j].u;
v1=E[j].v;
sn1=vset[u1];
sn2=vset[v1];
if(sn1!=sn2)
{
printf("边(%d,%d)权为:%d\n",u1,v1,E[j].w);
k++;
for(i=0;i<g.n;i++)
if(vset[i]==sn2)
vset[i]=sn1;
}
j++;
}
}
int main()
{
MGraph G1;
CreateMGraph(&G1);
PrintVex(G1);
PrintMatrix(G1);
Prim(G1,0);
Kruskal(G1);
MGraph G2;
CreateMGraph2(&G2);
PrintVex(G2);
PrintMatrix(G2);
Prim(G2,0);
Kruskal(G2);
}
修改void Kruskal(MGraph g)函数或者void InsertSort(Edge r[],int n)函数使得能输出正确的最小生成树