数据结构之最小生成树

一、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;
} 

 

点赞