一、Prim算法的实现
待补充、、、、
二、Kruskal算法的实现:
#include<iostream>
#include<algorithm>
using namespace std;
#define MaxInt 32767//表示无穷大(大于任何权值)
#define MVnum 100//Max Vertex Number
typedef char VertexType;//顶点数据类型
typedef int ArcType;//权值数据类型
typedef struct{
VertexType vexs[MVnum];//保存顶点的数组
ArcType arcs[MVnum][MVnum];//arcs[i][j]=w
int vexnum,arcnum;//顶点数;边数
}AMGraph;
struct Edge{ //Head->Tail=lowcost
VertexType Head;
VertexType Tail;
ArcType lowcost;
};
Edge edge[MVnum*(MVnum-1)/2];
bool cmp(Edge a,Edge b){
return a.lowcost<b.lowcost;
}
int Vexset[MVnum];//用来保存结点属于哪一个连通分支
int LocateVex(AMGraph G,VertexType v){//查找v在G中的数组下标
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==v){
return i;
break;
}
}
void CreateUDN(AMGraph &G){
cout<<"请输入无向网的顶点数和边数:";
cin>>G.vexnum>>G.arcnum;//输入无向网的顶点数和边数
cout<<"请输入这"<<G.vexnum<<"个顶点的名称:";
for(int i=0;i<G.vexnum;i++) cin>>G.vexs[i];//保存顶点
for(int i=0;i<G.vexnum;i++)//初始化所有边的权值为无限大
for(int j=0;j<G.vexnum;j++)
G.arcs[i][j]=MaxInt;
VertexType v1,v2;//定义两点和一边
ArcType w;
cout<<"请输入两顶点名称和边的权值:"<<endl;
for(int k=0;k<G.arcnum;k++){
cin>>v1>>v2>>w;//输入两点和一边
edge[k].Head=v1;//把信息保存到edge数组里
edge[k].Tail=v2;
edge[k].lowcost=w;
int i=LocateVex(G,v1);//查找v1,v2在图中的数组下标
int j=LocateVex(G,v2);
G.arcs[i][j]=w;//把信息保存在邻接矩阵里
G.arcs[j][i]=w;
}
}
void MinSpanTree_Kruskal(AMGraph G,int n){
sort(edge,edge+n,cmp);//按权值从小到大排序
for(int i=0;i<G.vexnum;i++) Vexset[i]=i;//初始化使得每个结点自身是一个连通分支
for(int i=0;i<G.vexnum;i++){
int v1=LocateVex(G,edge[i].Head);//查找v1,v2在图中的数组下标
int v2=LocateVex(G,edge[i].Tail);
int vs1=Vexset[v1];//把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;//并且把连通分支改为相同
}
}
}
int main(){
AMGraph G;
CreateUDN(G);
cout<<"最小生成树结果为:"<<endl;
MinSpanTree_Kruskal(G,G.arcnum);
return 0;
}