#include
#include
#define MAX 1000
#define MAXLEN 20
#define MAX_ARC_NUM 100
typedef char VertexType;
typedef int WeightType;
typedef struct Graph
{
VertexType vexs[MAXLEN];
int arc[MAXLEN][MAXLEN];
int vexnum, arcnum;
}MGraph;
typedef struct Node {
VertexType head,tail;
WeightType weight ;
} EdgeNode;
typedef struct {
VertexType vexs[MAXLEN];
EdgeNode edgelist[MAX_ARC_NUM];
int vexnum, arcnum;
} EGraph;
int locate(MGraph G, VertexType ch)
{
int i = 0;
while (G.vexs[i] != ch)
i++;
return i;
}
int locate(EGraph G, VertexType ch)
{
int i = 0;
while (G.vexs[i] != ch)
i++;
return i;
}
void CreateMGraph(MGraph &G)
{
int i,j,k;
int weight ;
VertexType v1;
VertexType v2;
printf("\n\n请输入无向网G的顶点数和边数(用逗号隔开) : ");
scanf("%d,%d",&G.vexnum,&G.arcnum);
fflush(stdin);
for(i=0;i<G.vexnum;i++)
{
printf("请输入第%d个顶点的值(以字符型表示) : ",i+1);
scanf("%c",&G.vexs[i]);
fflush(stdin);
}
for (i=0; i<G.vexnum; i++)
for (j=0; j<G.vexnum; j++)
{
if(i == j) G.arc[i][j] = 0;
else
G.arc[i][j] = MAX;
}
k=0;
while (k<G.arcnum)
{
printf("\n请输入第%d条边的信息(head,tail,weight):",k+1);
fflush(stdin);
scanf("%c,%c,%d", &v1,&v2,&weight);
i = locate(G,v1);
j = locate(G,v2);
G.arc[i][j] = weight;
G.arc[j][i] = G.arc[i][j];
k++;
}
}
void PrintMGraph(MGraph G)
{
int i,j;
printf("当前图的存储MGraph如下:\n");
printf("\n当前图的顶点集G.vexs为:\n");
printf("\n============================================\n");
for (i=0; i<G.vexnum; i++)
printf(" %c\t", G.vexs[i]);
printf("\n============================================\n");
printf("\n当前图的邻接矩阵G.arcs为:\n");
for (i=0; i<G.vexnum; i++)
{
printf("\n");
for (j=0; j<G.vexnum; j++)
{
if(G.arc[i][j]<MAX)
printf(" %d\t", G.arc[i][j]);
else
printf(" %c\t",'M');
}
}
}
void MiniSpanTree_Prim(MGraph G, VertexType ch)
{
int i, k,j;
struct
{
VertexType adjvex;
int lowcost;
}closedge[MAXLEN];
k = locate(G, ch);
system("cls");
printf("\n以%c为起始顶点的Prim最小生成树的边集为:\n",ch);
printf("\n head\t tail\t weight\n");
printf("-------------------------\n");
for (j=0; j<G.vexnum; j++)
if (j!=k)
{
closedge[j].adjvex = ch;
closedge[j].lowcost = G.arc[k][j];
}
closedge[k].adjvex = ch;
closedge[k].lowcost = 0;
for (i=1; i<G.vexnum; i++)
{
j = 0;
int min = MAX;
while (j < G.vexnum)
{
if (closedge[j].lowcost !=0 && min > closedge[j].lowcost)
{
min = closedge[j].lowcost;
k=j;
}
j++;
}
printf(" %c\t %c\t %d\n", closedge[k].adjvex, G.vexs[k], closedge[k].lowcost);
printf("-------------------------\n");
closedge[k].lowcost = 0;
for (j=0; j<G.vexnum; j++)
if (closedge[j].lowcost != 0 && closedge[j].lowcost > G.arc[k][j])
{
closedge[j].lowcost = G.arc[k][j];
closedge[j].adjvex = G.vexs[k];
}
}
}
void CreateEGraph(EGraph &G)
{
int i = 0;
VertexType v1;
VertexType v2;
printf("\n\n请输入无向网G的顶点数和边数(用逗号隔开) : ");
scanf("%d,%d",&G.vexnum,&G.arcnum);
fflush(stdin);
for(i=0;i<G.vexnum;i++)
{
printf("请输入第%d个顶点的值(以字符型表示) : ",i+1);
scanf("%c",&G.vexs[i]);
fflush(stdin);
}
i=0;
while (i<G.arcnum)
{
printf("\n请输入第%d条边的信息(head,tail,weight):",i+1);
fflush(stdin);
scanf("%c,%c,%d", &G.edgelist[i].head,&G.edgelist[i].tail,&G.edgelist[i].weight);
i++;
}
system("cls");
}
void PrintEGraph(EGraph G)
{
int i;
printf("\n当前图的顶点集G.vexs为:\n");
printf("\n============================================\n");
for (i=0; i<G.vexnum; i++)
printf(" %c\t", G.vexs[i]);
printf("\n============================================\n");
printf("\n当前图的边集G.edgelist为:\n");
printf("\n i\thead\ttail\tweight\n");
printf("-------------------------------\n");
for (i=0; i<G.arcnum; i++)
{
printf(" %d\t %c\t %c\t %d \n", i+1,G.edgelist[i].head,G.edgelist[i].tail,G.edgelist[i].weight);
printf("-------------------------------\n");
}
}
void sort(EGraph &G)
{
int i, j,swapflag=1;
EdgeNode t;
for(i = 0; i <G.arcnum-1&&swapflag; i++)
{
swapflag=0;
for(j = 0; j<G.arcnum-1-i; j++)
if(G.edgelist[j ].weight > G.edgelist[j+1].weight)
{t.head= G.edgelist[j].head;
t.tail=G.edgelist[j].tail;
t.weight=G.edgelist[j].weight;
G.edgelist[j].head=G.edgelist[j+1].head;
G.edgelist[j].tail=G.edgelist[j+1].tail;
G.edgelist[j].weight=G.edgelist[j+1].weight;
G.edgelist[j+1].head=t.head;
G.edgelist[j+1].tail=t.tail;
G.edgelist[j+1].weight=t.weight;
swapflag=1;}
}
}
void MiniSpanTree_Kruscal(EGraph &G)
{
EdgeNode *TE ;
int i,j,k,v,s1,s2,*Vset ;
TE=(EdgeNode*)malloc((G.vexnum-1)*sizeof(EdgeNode)) ;
Vset=(int*)malloc(G.vexnum*sizeof(int)) ;
for (j=0; j<G.vexnum; j++)
Vset[j]=j ;
sort(G) ;
printf("将图的边集排序后图G为:\n");
PrintEGraph(G);
j=0 ; k=0 ;
while (k< G.vexnum-1&&j< G.arcnum)
{
s1=Vset[locate(G,G.edgelist[j].head)] ;
s2=Vset[locate(G,G.edgelist[j].tail)] ;
if (s1!=s2)
{ TE[k].head=G.edgelist[j].head ;
TE[k].tail=G.edgelist[j].tail ;
TE[k].weight=G.edgelist[j].weight ;
k++ ;
for (v=0; v<G.vexnum; v++)
if (Vset[v]==s2) Vset[v]=s1 ;
}
j++ ;
}
free(Vset) ;
printf("\nKruscal最小生成树中的边集为:\n");
printf(" i\thead\ttail\tweight\n");
printf("-------------------------------\n");
for(j=0;j<G.vexnum-1;j++)
{
printf(" %d\t %c\t %c\t %d\n",j+1,TE[j].head,TE[j].tail,TE[j].weight);
printf("-------------------------------\n");
}
}
void menu()
{
printf("\n|===================================|\n");
printf("| ****---- 选择式菜单 ----**** |\n");
printf("|===================================|\n");
printf("| |\n");
printf("| 1:创建图G的MGraph存储 |\n");
printf("| |\n");
printf("| 2:输出图G的MGraph存储 |\n");
printf("| |\n");
printf("| 3:构造普里姆最小生成树 |\n");
printf("| |\n");
printf("| 4:创建图G的EGraph存储 |\n");
printf("| |\n");
printf("| 5:输出图G的EGraph存储 |\n");
printf("| |\n");
printf("| 6:构造克鲁斯卡尔最小生成树|\n");
printf("| |\n");
printf("| 0:退出菜单 |\n");
printf("| |\n");
printf("|===================================|\n");
}
int main()
{
MGraph G1;
EGraph G2;
char ch;
int k;
int exitflag=0;
while(!exitflag)
{
menu();
printf("请输入你的菜单选项:");
scanf("%d",&k);
switch(k){
case 0: exitflag=1;
break;
case 1:
system("cls");
CreateMGraph(G1);
system("cls");
break;
case 2:
system("cls");
PrintMGraph(G1);
break;
case 3:
system("cls");
printf("PRIM最小生成树过程如下:\n");
printf("\n请输入构造普里姆生成树的起始顶点:");
fflush(stdin);
scanf("%c", &ch);
MiniSpanTree_Prim(G1, ch);
break;
case 4:
system("cls");
CreateEGraph(G2);
system("cls");
break;
case 5:
system("cls");
PrintEGraph(G2);
break;
case 6:
system("cls");
printf("Kruscal最小生成树过程如下:\n");
MiniSpanTree_Kruscal(G2);
break;
default:
system("cls");
printf("警告!你给的选项号非法,请重新输入\n");
break; }
}
return 0;
}