如图,输出最小生成树的生成过程
算法思想:
- 每个边的权值进行从小到大排序
- 然后从小到大添加到最小生成树中,若添加一个边后构成环路,则此边不能添加。直到每个顶点都加入到最小生成树中。
- 需要一个结构体来存储 每个边的权值与始末顶点。再进行排序。
struct
{
VexType head;
VexType tail;
ArcType lowcost;
}Edge[MAXSIZE]; //存入每条边的首尾以及权值
通过无向图写出邻接矩阵,调用函数创建邻接矩阵
VexType vexs[7] = {'0','1','2','3','4','5','6'};
ArcType arcs[7][7] = {{0,17,MAXNUM,MAXNUM,MAXNUM,10,MAXNUM},
{17,0,16,MAXNUM,MAXNUM,MAXNUM,14},
{MAXNUM,16,0,12,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,12,0,19,MAXNUM,18},
{MAXNUM,MAXNUM,MAXNUM,19,0,25,24},
{10,MAXNUM,MAXNUM,MAXNUM,25,0,MAXNUM},
{MAXNUM,14,MAXNUM,18,24,MAXNUM,0}};
CreateMGraph(G,vexs,arcs,7); //建表
克鲁斯卡尔图表法
代码
#ifndef _MGraph_H_
#define _MGraph_H_
#include <iostream>
using namespace std;
#define OK 1
#define ERROR -1
#define OVERFLOW -2
#define MAXSIZE 100
#define MAXNUM 99999 //无穷大
typedef int Status;
typedef char VexType;
typedef int ArcType;
typedef struct
{
VexType Vexs[MAXSIZE]; //点表
ArcType Arcs[MAXSIZE][MAXSIZE]; //边表
int Vexnum; //顶点个数
int Arcnum; //边数
}MGraph;
Status initMGraph(MGraph &G)
{
G.Vexnum = G.Arcnum = 0;
return OK;
}
Status CreateMGraph(MGraph &G,VexType vexs[],ArcType arcs[][7],int n) //n为顶点个数
{
for (int i = 0; i < n; i++)
G.Vexs[i] = vexs[i];
G.Vexnum = n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (arcs[i][j] != 0 && arcs[i][j] != MAXNUM)
G.Arcnum++; //对于无向图 除以二即可
G.Arcs[i][j] = arcs[i][j];
}
return OK;
}
Status LocateVex(MGraph G,VexType e)
{
for (int i = 0; i < G.Vexnum; i++)
if (G.Vexs[i] == e)
return i;
return -1;
}
struct
{
VexType head;
VexType tail;
ArcType lowcost;
}Edge[MAXSIZE]; //存入每条边的首尾以及权值
int Vexset[MAXSIZE]; //每个顶点所属的连通分量的编号
void CreateEdge(MGraph G)
{
int k = 0; //Edge数组的下标
for (int i = 0; i < G.Vexnum; i++)
for (int j = i; j < G.Vexnum; j++) //无向图只需在上三角遍历即可
if (G.Arcs[i][j] != 0 && G.Arcs[i][j] != MAXNUM)
{
Edge[k].head = G.Vexs[i];
Edge[k].tail = G.Vexs[j];
Edge[k].lowcost = G.Arcs[i][j];
k++; //最终k的值为G.Arcnum / 2;
}
}
void Sort(MGraph G) //直接插入排序
{
CreateEdge(G);
int i, j;
for (int i = 1; i < G.Arcnum / 2; i++)
{
if (Edge[i].lowcost < Edge[i - 1].lowcost)
{
VexType head = Edge[i].head;
VexType tail = Edge[i].tail;
ArcType lowcost = Edge[i].lowcost;
for (j = i - 1; lowcost < Edge[j].lowcost; j--)
Edge[j + 1] = Edge[j];
Edge[j + 1].head = head;
Edge[j + 1].tail = tail;
Edge[j + 1].lowcost = lowcost;
}
}
}
void Kruskal(MGraph G) //核心算法
{
Sort(G); //选出Edge中的一个最小边
for (int i = 0; i < G.Vexnum; i++) //初始化每个顶点为一个连通分量
Vexset[i] = i;
for (int i = 0; i < G.Arcnum / 2; i++)
{
int v1 = LocateVex(G,Edge[i].head);
int v2 = LocateVex(G,Edge[i].tail);
int vs1 = Vexset[v1];
int vs2 = Vexset[v2];
if (vs1 != vs2) //说明两者不会构成环路,加入到最小生成树
{
cout << Edge[i].head << "," << Edge[i].tail << " "<<endl; //输出边
for (int j = 0; j < G.Vexnum; j++)
if (Vexset[j] == vs2) Vexset[j] = vs1; //将连通分量vs2的改为vs1
}
}
}
#endif
结果
来源:CSDN
作者:iboylee
链接:https://blog.csdn.net/weixin_41546300/article/details/104731519