最小生成樹演算法程式碼
阿新 • • 發佈:2019-02-09
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<iostream> 4 #define MAX_VERTEX_NUM 20 5 #define OK 1 6 #define ERROR 0 7 #define MAX 1000 8 using namespace std; 9 typedef struct Arcell 10 { 11 double adj; 12 }Arcell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];13 typedef struct 14 { 15 char vexs[MAX_VERTEX_NUM]; //節點陣列 16 AdjMatrix arcs; //鄰接矩陣 17 int vexnum, arcnum; //圖的當前節點數和弧數 18 }MGraph; 19 typedef struct Pnode //用於普利姆演算法 20 { 21 char adjvex; //節點 22 double lowcost; //權值 23 }Pnode,Closedge[MAX_VERTEX_NUM]; //記錄頂點集U到V-U的代價最小的邊的輔助陣列定義 24typedef struct Knode //用於演算法中儲存一條邊及其對應的2個節點 25 { 26 char ch1; //節點1 27 char ch2; //節點2 28 double value;//權值 29 }Knode,Dgevalue[MAX_VERTEX_NUM]; 30 //----------------------------------------------------------------------------------- 31 int CreateUDG(MGraph & G,Dgevalue & dgevalue);32 int LocateVex(MGraph G,char ch); 33 int Minimum(MGraph G,Closedge closedge); 34 void MiniSpanTree_PRIM(MGraph G,char u); 35 void Sortdge(Dgevalue & dgevalue,MGraph G); 36 //----------------------------------------------------------------------------------- 37 int CreateUDG(MGraph & G,Dgevalue & dgevalue) //構造無向加權圖的鄰接矩陣 38 { 39 int i,j,k; 40 cout<<"請輸入圖中節點個數和邊/弧的條數:"; 41 cin>>G.vexnum>>G.arcnum; 42 cout<<"請輸入節點:"; 43 for(i=0;i<G.vexnum;++i) 44 cin>>G.vexs[i]; 45 for(i=0;i<G.vexnum;++i)//初始化陣列 46 { 47 for(j=0;j<G.vexnum;++j) 48 { 49 G.arcs[i][j].adj=MAX; 50 } 51 } 52 cout<<"請輸入一條邊依附的定點及邊的權值:"<<endl; 53 for(k=0;k<G.arcnum;++k) 54 { 55 cin >> dgevalue[k].ch1 >> dgevalue[k].ch2 >> dgevalue[k].value; 56 i = LocateVex(G,dgevalue[k].ch1 ); 57 j = LocateVex(G,dgevalue[k].ch2 ); 58 G.arcs[i][j].adj = dgevalue[k].value; 59 G.arcs[j][i].adj = G.arcs[i][j].adj; 60 } 61 return OK; 62 } 63 int LocateVex(MGraph G,char ch) //確定節點ch在圖G.vexs中的位置 64 { 65 int a ; 66 for(int i=0; i<G.vexnum; i++) 67 { 68 if(G.vexs[i] == ch) 69 a=i; 70 } 71 return a; 72 } 73 //typedef struct Pnode //用於普利姆演算法 74 //{ 75 // char adjvex; //節點 76 // double lowcost; //權值 77 //}Pnode,Closedge[MAX_VERTEX_NUM]; //記錄頂點集U到V-U的代價最小的邊的輔助陣列定義 78 void MiniSpanTree_PRIM(MGraph G,char u)//普利姆演算法求最小生成樹 79 { 80 int i,j,k; 81 Closedge closedge; 82 k = LocateVex(G,u); 83 for(j=0; j<G.vexnum; j++) 84 { 85 if(j != k) 86 { 87 closedge[j].adjvex = u; 88 closedge[j].lowcost = G.arcs[k][j].adj; 89 } 90 } 91 closedge[k].lowcost = 0; 92 for(i=1; i<G.vexnum; i++) 93 { 94 k = Minimum(G,closedge); 95 cout<<"("<<closedge[k].adjvex<<","<<G.vexs[k]<<","<<closedge[k].lowcost<<")"<<endl; 96 closedge[k].lowcost = 0; 97 for(j=0; j<G.vexnum; ++j) 98 { 99 if(G.arcs[k][j].adj < closedge[j].lowcost) 100 { 101 closedge[j].adjvex = G.vexs[k]; 102 closedge[j].lowcost= G.arcs[k][j].adj; 103 } 104 } 105 } 106 } 107 int Minimum(MGraph G,Closedge closedge) //求closedge中權值最小的邊,並返回其頂點在vexs中的位置 108 { 109 int i,j; 110 double k = 1000; 111 for(i=0; i<G.vexnum; i++) 112 { 113 if(closedge[i].lowcost != 0 && closedge[i].lowcost < k) 114 { 115 k = closedge[i].lowcost; 116 j = i; 117 } 118 } 119 return j; 120 } 121 void MiniSpanTree_KRSL(MGraph G,Dgevalue & dgevalue)//克魯斯卡爾演算法求最小生成樹 122 { 123 int p1,p2,i,j; 124 int bj[MAX_VERTEX_NUM]; //標記陣列 125 for(i=0; i<G.vexnum; i++) //標記陣列初始化 126 bj[i]=i; 127 Sortdge(dgevalue,G);//將所有權值按從小到大排序 128 for(i=0; i<G.arcnum; i++) 129 { 130 p1 = bj[LocateVex(G,dgevalue[i].ch1)]; 131 p2 = bj[LocateVex(G,dgevalue[i].ch2)]; 132 if(p1 != p2) 133 { 134 cout<<"("<<dgevalue[i].ch1<<","<<dgevalue[i].ch2<<","<<dgevalue[i].value<<")"<<endl; 135 for(j=0; j<G.vexnum; j++) 136 { 137 if(bj[j] == p2) 138 bj[j] = p1; 139 } 140 } 141 } 142 } 143 void Sortdge(Dgevalue & dgevalue,MGraph G)//對dgevalue中各元素按權值按從小到大排序 144 { 145 int i,j; 146 double temp; 147 char ch1,ch2; 148 for(i=0; i<G.arcnum; i++) 149 { 150 for(j=i; j<G.arcnum; j++) 151 { 152 if(dgevalue[i].value > dgevalue[j].value) 153 { 154 temp = dgevalue[i].value; 155 dgevalue[i].value = dgevalue[j].value; 156 dgevalue[j].value = temp; 157 ch1 = dgevalue[i].ch1; 158 dgevalue[i].ch1 = dgevalue[j].ch1; 159 dgevalue[j].ch1 = ch1; 160 ch2 = dgevalue[i].ch2; 161 dgevalue[i].ch2 = dgevalue[j].ch2; 162 dgevalue[j].ch2 = ch2; 163 } 164 } 165 } 166 } 167 void main() 168 { 169 int i,j; 170 MGraph G; 171 char u; 172 Dgevalue dgevalue; 173 CreateUDG(G,dgevalue); 174 cout<<"圖的鄰接矩陣為:"<<endl; 175 for(i=0; i<G.vexnum; i++) 176 { 177 for(j=0; j<G.vexnum; j++) 178 cout << G.arcs[i][j].adj<<" "; 179 cout<<endl; 180 } 181 cout<<"=============普利姆演算法===============\n"; 182 cout<<"請輸入起始點:"; 183 cin>>u; 184 cout<<"構成最小代價生成樹的邊集為:\n"; 185 MiniSpanTree_PRIM(G,u); 186 cout<<"============克魯斯科爾演算法=============\n"; 187 cout<<"構成最小代價生成樹的邊集為:\n"; 188 MiniSpanTree_KRSL(G,dgevalue); 189 }