在写kruskal算法时,输入6个节点,9条边,但是输入第一个边之后程序输出直接跑飞了
代码如下,感觉不像是CreatVDN()函数出现的问题,但是输入却在输入边的权值的时候跑飞了,请问有没有指点一下
前面的代码都是一些功能性的函数,最主要是最后的kruskal()函数
#include<iostream>
using namespace std;
//kruskal算法最小生成树
#define max_weight 32767
//邻接矩阵来表示图
typedef struct
{
char vexs[100]; //这里相比较书上多了顶点数组
int arcs[100][100];
int vexnum,arcnum;
}AMGraph;
//定义边
typedef struct
{
char begin;
char end;
int lowcost;
}EDGE;
//定义Edge数组
EDGE Edge[99*50];
//找出顶点在顶点数组的位置,如果没这个顶点,返回-1
int LocateVex(AMGraph G,char v)
{
for(int i=0;i<G.vexnum;i++)
{
if(G.vexs[i]==v)
{
return i;
}
}
return -1;
}
//为无向图赋值,同时Edge数组初始化
void CreatVDN(AMGraph &G)
{
int i,j,k;
cout<<"input the number of vexnum and arcnum separate with space key"<<endl;
cin>>G.vexnum>>G.arcnum;
cout<<endl;
//输入顶点
cout<<"input name of vertex"<<endl;
for(i=0;i<G.vexnum;i++)
{
cout<<"input No."<<i+1<<" vertex"<<endl;
cin>>G.vexs[i];
}
//邻接矩阵初始化
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
if(i==j)
{
G.arcs[i][j]=0;
}
G.arcs[i][j]=max_weight;
}
}
//手动输入邻接矩阵
cout<<"input the weight of arc :weight vex1 vex2"<<endl;
int weight;
int vex1,vex2;
for(k=0;k<G.arcnum;++k)
{
cout<<"input the No."<<k+1<<" arc"<<endl;
cin>>weight>>vex1>>vex2;
i=LocateVex(G,vex1);
j=LocateVex(G,vex2);
if(i==-1 || j==-1) //如果有一个vex没找到就输出error
{
cout<<"error"<<endl;
k--;
}
else //如果找到了就初始化邻接矩阵和Edge数组
{
G.arcs[i][j]=weight;
G.arcs[j][i]=G.arcs[i][j];
Edge[k].lowcost=weight; //同时对Edge数组也进行初始化
Edge[k].begin=vex1;
Edge[k].end=vex2;
}
}
}
//冒泡法对边从小到大排序
void sort(EDGE Edge[],AMGraph G)
{
char temp_begin,temp_end;
int temp_weight;
for(int i=0;i<G.arcnum-1;i++)
{
for(int j=0;j<G.arcnum-1-i;j++)
{
if(Edge[j].lowcost>Edge[j+1].lowcost)
{
temp_begin=Edge[j].begin;
Edge[j].begin=Edge[j+1].begin;
Edge[j+1].begin=temp_begin;
temp_end=Edge[j].end;
Edge[j].end=Edge[j+1].end;
Edge[j+1].end=temp_end;
temp_weight=Edge[j].lowcost;
Edge[j].lowcost=Edge[j+1].lowcost;
Edge[j+1].lowcost=temp_weight;
}
}
}
cout<<"after sorting the Edge[] is:"<<endl;
for(int i=0;i<G.arcnum;i++)
{
cout<<Edge[i].begin<<"\t"<<Edge[i].end<<"\t"<<Edge[i].lowcost<<endl;
}
}
//寻找根节点,输入是parent数组和要寻找其根节点的元素序号
//输出是根节点的序号
int Find(int *parent,int L)
{
while(parent[L]>-1)
{
L=parent[L];
}
return L;
}
//kruskal算法
void kruskal(AMGraph G)
{
//1.根据G的邻接矩阵初始化edge数组
//2.对edge数组进行排序
//3.创建parnet数组,根据edge数组对parent数组进行处理,并在处理时输出最小生成树的边
int i,j;
int k=0;
int v1,v2; //用来装结点的在edge数组中的序号
int vex1,vex2; //用来装寻找到的根节点
for(i=0;i<G.vexnum-1;i++) //按照邻接矩阵的上三角来填充edge数组
for(j=i+1;j<G.vexnum;j++)
{
if(G.arcs[i][j]<max_weight)
{
Edge[k].lowcost=G.arcs[i][j];
Edge[k].begin=i;
Edge[k].end=j;
k++; //Edge数组中的元素个数,虽然不一样用得上
}
}
}
//Edge数组排序
sort(Edge,G); //sort自带排序后输出
cout<<endl;
int parent[G.vexnum];
for(i=0;i<G.vexnum;i++)
{
parent[i]=-1; //根节点在parent数组中的值默认为-1
}
//处理,输出最小生成树
cout<<"mini tree :"<<endl;
for(int num=0,i=0;i<G.arcnum && num<G.vexnum-1;i++) //两个停止循环条件:要么循环完了,还没找到足够的边生成最小生成树,要么没循环完就找齐了边来生成最小生成树
{
v1=LocateVex(G,Edge[i].begin); //v1是Edge[i].begin在G中的元素序号
v2=LocateVex(G,Edge[i].end);
vex1=Find(parent,v1); //vex1对应的元素在parent数组中的根节点
vex2=Find(parent,v2);
if(vex1!=vex2) //如果是不同的树,就合并且生成一条边
{
parent[vex2]=vex1;
cout<<Edge[i].begin<<"-->"<<Edge[i].end<<endl;
num++;
}
}
}
int main()
{
AMGraph G;
CreatVDN(G); //这里是引用,引用在使用时实参不需要加&
kruskal(G);
system("pause");
return 0;
}