最小生成树算法代码
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的代价最小的边的辅助数组定义 24 typedef 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 }