邻接矩阵+边集数组+克鲁斯卡尔

题目描述:

利用克鲁斯卡尔的方法生成最小树。

分析:

这个方法简单粗暴。
邻接矩阵讲解:https://blog.csdn.net/qq_43506138/article/details/86599865
简单的讲,就是将边集数组中的边依次打印就好,不过在打印的前提是所要即将打印的这条边不会和之前打印的边成为回路。
所以,这个方法只要在把边集数组转换出来后,在一个函数判断回路就可以了。

#include"stdio.h"
#include"string.h"
#include"stdlib.h"
typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define MAXEDGE 100
#define INFINITY 65535
typedef struct
{
    VertexType vexs[MAXVEX];
    EdgeType arc[MAXVEX][MAXVEX];
    int numEdge,numVexs;
}MGraph;
typedef struct
{
    int begin;
    int end;
    int weight;
}Edge;
void CreateMGraph(MGraph *G)
{
    int i,j,k,weight;
    printf("请输入顶点数和边数:\n");
    scanf("%d%d",&G->numVexs,&G->numEdge);
    for(i=0;inumVexs;i++)   //初始化邻接矩阵
        for(j=0;jnumVexs;j++)
           {
               if(i==j)
                  G->arc[i][j]=0;
               else
                G->arc[i][j]=INFINITY;
           }
    for(k=0;knumEdge;k++)
    {
        printf("请输入边的相关信息(包括权):\n");
        scanf("%d%d%d",&i,&j,&weight);
        G->arc[i][j]=weight;
        G->arc[j][i]=weight;
    }
}
//将邻接矩阵转化为边集数组
void TransEdge(Edge edge[],MGraph *G)
{
    int i,j,k=0;
    //依次将邻接矩阵中的有权的地方保存下来
    for(i=0;inumEdge;i++)
        for(j=0;jnumEdge;j++)
            {
                if(G->arc[i][j]!=0&&G->arc[i][j]!=INFINITY)
                {
                    edge[k].begin=i;
                    edge[k].end=j;
                    edge[k].weight=G->arc[i][j];
                    k++;
                }
            }
  //按照权排序
    for(i=0;iedge[j].weight)
                {
                    Edge T;
                    T=edge[i];edge[i]=edge[j];edge[j]=T;
                }
            }
}
//查找连线顶点的尾部下标
int Find(int *parent,int f)
{
    while(parent[f]>0)
        f=parent[f];
    return f;
}
//最小生成树(克鲁斯卡尔)
void MiniSpanTree_Kruskal(MGraph G)
{
    int i,j,k;
    Edge edge[MAXEDGE];//边集数组
    int parent[MAXVEX];//判断边与边之间是否形成回路的用处
    for(i=0;i

本代码难点在于Find函数和parent数组的理解,多演示几次就能很好理解了。简单的讲,Find函数,就是查找这个顶点线路的最后一个顶点

你可能感兴趣的:(吉首刷题路,图,图论)