最小生成树算法代码

  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 }
原文地址:https://www.cnblogs.com/2011winseu/p/3137904.html