最小生成树问题学习总结

来源:互联网 发布:apache运行python 编辑:程序博客网 时间:2024/06/04 19:20

kruskal算法思想:

对图中的所有边按升序排列,依次检验图中的权值最小的边,若此边加入后不形成回路,则选取此边加入生成树,直至选取n-1条边。

算法实现:

对图的信息中所需数据元素只有边的两端顶点及权值,选取的生成树的边存储结构与之相同。

是否形成回路的判断需要用到待选边表,这里用vset数组,若两顶点在同一集合中(vset[i]==vset[j]),则不能选取边L<i,j>,不然会形成回路。

这里推荐MOOC中国大学网上的--解放军理工大学的数据结构课程,讲解特别详细。

#include <iostream>#include <algorithm>using namespace std;struct linknode{int vex1,vex2;int weight;};struct elgraph{int vexnum,edgenum;};linknode *kruskal_MST(elgraph *G){linknode *edgelist=new linknode[G->edgenum];//这里是输入G图中的都有边for(int i=0;i<G->edgenum;i++)cin>>edgelist[i].vex1>>edgelist[i].vex2>>edgelist[i].weight;linknode *TE=new linknode[G->vexnum-1];//TE数组存放最小生成树的边int j,k,v,s1,s2;int *vset=new int[G->vexnum];//用待选边表vset来判断是否形成回路int w;for(j=0;j<G->vexnum;j++)//vset初始化vset[j]=j;sort(edgelist[0],edgelist[G->edgenum+1]);//按照权值大小给图中的边排序j=0;k=0;//k表示遍历的顶点数,j表示遍历的边的数目while(k<G->vexnum-1&&j<G->edgenum){s1=vset[edgelist[j].vex1];s2=vset[edgelist[j].vex2];if(s1!=s2)//生成树中加入边L<s1,s2>后不会生成回路{TE[k].vex1=edgelist[j].vex1;//加入此边TE[k].vex2=edgelist[j].vex2;TE[k].weight=edgelist[j].weight;k++;for(v=0;v<G->vexnum;v++)//修改待选边表if(vset[v]==s2) vset[v]=s1;}j++;}return TE;}

prim算法

//最小生成树之prim算法#include <iostream>using namespace std;const int  M=100;struct edgenode{int incrvert,vertex;int weight;};void prim(int G[M][M],int n){int v,i,j,k;edgenode t,wait[M-1];//wait为待选边表for(v=0;v<n-1;n++)//以数组标号0的顶点为初始生长点初始化待选边表{wait[v].incrvert=0;wait[v].vertex=v+1;wait[v].weight=G[0][v+1];}for(i=0;i<n-2;i++){k=i;for(j=i+1;j<n-1;j++){if(wait[j].weight<wait[k].weight)k=j;t=wait[k];wait[k]=wait[i];wait[i]=t;v=wait[i].vertex;for(j=i+1;j<n-1;j++)if(wait[j].weight>G[v][wait[j].vertex]){wait[j].weight=G[v][wait[j].vertex];wait[j].incrvert=v;}}for(i=0;i<n-1;i++)cout<<wait[i].vertex<<wait[i].incrvert<<wait[i].weight;     }


0 0