#include <iostream>
#define MAXVEX 6 //结点数(初始默认6顶点,更改的话直接在这里修改即可)
#define MAXEDGE 10 //边数(初始默认10条边,更改的话直接在这里修改即可)
#define INFINITY 65535 //表示无穷大
using namespace std;
//普利姆最小生成树原理:
//步骤1:确定s和c两个集合,s放生成树结点,c放其余结点
//步骤2:先选一个结点1放入s,此时结点1在s中,其余结点在c中
//步骤3:在与s中的结点1相邻的结点中选出权值最小的那个结点2放入s中,此时s中有结点1和2
//步骤4:在与s中的结点1(结点2)相邻的结点中选出权值最小的那个结点3放入s中,此时s中有结点1和2和3
//步骤5:以此类推........
//下面代码是无向图的邻接矩阵的普利姆算法
//注意点:下标0的位置都不用,所以要多开辟一个空间
//若改为有向图的邻接矩阵普利姆算法,则:
//1.删除下面的一句代码g.matrix[n][m]=1;
typedef struct
{
int vexNum; //顶点数
int edgeNum; //边数
int matrix[MAXVEX+1][MAXVEX+1]; //二维数组表示矩阵
char vexinfo[MAXVEX+1]; //存放结点数组的值(如A,B,C,D)
}AdjMatr; //邻接矩阵
/*********************初始化邻接矩阵************************/
void initAdjMatr(AdjMatr &g )
{
g.vexNum = MAXVEX; //顶点数
g.edgeNum = MAXEDGE; //边数
//初始化矩阵信息,初始为,一个不可能的数字表示这两个顶点之间不存在边
for(int i=1;i<=MAXVEX;i++)
{
for(int j=1;j<=MAXVEX;j++)
g.matrix[i][j]=INFINITY;
}
//初始化结点信息,(如A,B,C,D)
for(int i=1;i<=MAXVEX;i++)
{
cout<<"请输入第"<<i<<"个结点的信息:";
cin>>g.vexinfo[i];
}
}
//通过结点信息(A,B,C,D之类)来查找对应矩阵下标
/*********************确定边在矩阵的位置*********************/
void locata(AdjMatr &g,char &vex1,char &vex2, int &m, int &n)
{
for(int i =1;i<=MAXVEX;i++)
{
if(vex1 == g.vexinfo[i])
m=i;
if(vex2 == g.vexinfo[i])
n=i;
}
}
/*********************创建图对应的邻接矩阵************************/
void setAdjMatr(AdjMatr &g)
{
//根据输入的两个顶点,来更新矩阵的值
for(int i=1;i<=g.edgeNum;i++)
{
int weight;//两边之间的权值
char vex1,vex2; //接受输入的两个顶点,来表示从vex1到vex2这条边
cout<<"请输入边的信息(形如A B,表示从A到B的一条边):";
cin>>vex1>>vex2>>weight;
int m,n; //m和n是用来接受vex1和vex2所在的下标值,好据此更新矩阵相应位置的值
locata(g,vex1,vex2,m,n);
g.matrix[m][n]=weight;
g.matrix[n][m]=weight;//无向图邻接矩阵对称,少掉这句代码就是有向图的邻接矩阵了
}
}
/*********************普利姆算法***************************/
void prim(AdjMatr &g)
{
int Min ,i,j,k;
int adjvex[MAXVEX+1]; //保存相关顶点的下标
int lowcost[MAXVEX+1]; //保存相关顶点间边的权值
lowcost[1]=0; //lowcost[i]的值为0,表示结点i已经加入生成树,开始先将结点1加入生成树
adjvex[1]=1; //初始化第1个顶点的下标为1(生成树的第一个顶点)
for(i=2;i<=g.vexNum;i++)
{
lowcost[i]=g.matrix[1][i]; //将与顶点1有关的边的权值存入数组
adjvex[i]=1; //初始化都为第一个进入生成树的顶点的下标
}
for(i=2;i<=g.vexNum;i++)
{
Min=INFINITY; //初始化最小权值为无穷大
j=2;k=1;
//因为此时lowcost[1]已经是0,即已在生成树中,所以,这里j从2开始
while(j<=g.vexNum) //循环全部顶点,找出这一次权值最小的结点
{ //lowcost权值不为0且权值小于Min
if(lowcost[j] != 0 && lowcost[j]<Min)
{
Min=lowcost[j];
k=j; //k用来保存这一次最小权值的下标
}
j++;
}
cout<<"("<<adjvex[k]<<","<<k<<")"<<endl; //输出这一轮的最小边
lowcost[k]=0; //每次将结点加进生成树后都要把lowcost设为0
for(j=2;j<=g.vexNum;j++)//再次循环所有顶点
{ //因为此时lowcost[1]已经是0,即已在生成树中,所以,这里j从2开始
if(lowcost[j] != 0 && g.matrix[k][j] <lowcost[j])
{
lowcost[j] = g.matrix[k][j];
adjvex[j]=k;
}
}
}
}
int main()
{
AdjMatr g;
initAdjMatr(g);
setAdjMatr(g);
prim(g);
return 0;
}
C++数据结构-普利姆算法最小生成树
猜你喜欢
转载自blog.csdn.net/weixin_43323201/article/details/84778283
今日推荐
周排行