資料結構之最小生成樹
阿新 • • 發佈:2018-12-19
一、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; }