1. 程式人生 > >資料結構之最小生成樹

資料結構之最小生成樹

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