(1)Prim
算法如下,头文件:
#defineINFINITY10000
#defineMAX_VERTEX_NUM20
typedefintInfoType;
typedefcharVertexType;
typedefintVRType;

typedefenum...{DG,DN,UDG,UDN}GraphKind;

typedefstructArcCell...{
VRTypeadj;
InfoType*info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedefstruct...{
VertexTypevexs[MAX_VERTEX_NUM];
AdjMatrixarcs;
intvexnum,arcnum;
GraphKindkind;
}MGraph;

intweight[][6]=...{
...{0,6,1,5,INFINITY,INFINITY},
...{6,0,5,INFINITY,3,INFINITY},
...{1,5,0,5,6,4},
...{5,INFINITY,5,0,INFINITY,2},
...{INFINITY,3,6,INFINITY,0,6},
...{INFINITY,INFINITY,4,2,6,0}
};
//#defineINPUT1

typedefstruct...{
intparent;
intcost;
}mst_prim_closedge;
源文件:
#include"graph.h"
#include"stdio.h"
#include"stdlib.h"

voidcreateDG(MGraph&g)...{}
voidcreateDN(MGraph&g)...{}
voidcreateUDG(MGraph&g)...{}

intlocate(MGraphg,charname)...{
for(inti=0;i<g.vexnum;i++)...{
if(name==g.vexs[i])...{
returni;
}
}
return-1;
}

voidcreateUDN(MGraph&g)...{
#ifdefINPUT
printf("inputthenumberofvertexandarcs: ");
scanf("%d%d",&g.vexnum,&g.arcnum);
fflush(stdin);
#else
printf("inputthenumberofvertex: ");
scanf("%d",&g.vexnum);
fflush(stdin);
#endif
inti=0,j=0,k=0;
printf("inputthenameofvertex: ");

for(i=0;i<g.vexnum;i++)...{
scanf("%c",&g.vexs[i]);
fflush(stdin);
}

for(i=0;i<g.vexnum;i++)...{
for(j=0;j<g.vexnum;j++)...{
g.arcs[i][j].adj=INFINITY;
g.arcs[i][j].info=NULL;
}
}
#ifdefINPUT
charv1,v2;
intw;
printf("inputthe%darcsv1v2andweight: ",g.arcnum);
for(k=0;k<g.arcnum;k++)...{
scanf("%c%c%d",&v1,&v2,&w);
fflush(stdin);
i=locate(g,v1);
j=locate(g,v2);
g.arcs[i][j].adj=w;
}
#else
printf("nowconstructingthematrixofgraph... ");
for(i=0;i<g.vexnum;i++)...{
for(j=0;j<g.vexnum;j++)...{
g.arcs[i][j].adj=weight[i][j];
}
}
#endif
}

voidprintGraph(MGraphg)...{
for(inti=0;i<g.vexnum;i++)...{
for(intj=0;j<g.vexnum;j++)...{
printf("%d ",g.arcs[i][j].adj);
}
printf(" ");
}
}

voidcreateGragh(MGraph&g)...{
printf("pleaseinputthetypeofgraph: ");
scanf("%d",&g.kind);

switch(g.kind)...{
caseDG:
createDG(g);
break;
caseDN:
createDN(g);
break;
caseUDG:
createUDG(g);
break;
caseUDN:
createUDN(g);
printGraph(g);
break;
}
}
//getthemincostvertice,returntheindex
intminimum(mst_prim_closedge*closedge,intn)...{
intret=-1;
intretcost=INFINITY;
for(inti=0;i<n;i++)...{
if(closedge[i].cost>0&&closedge[i].cost<retcost)...{
ret=i;
retcost=closedge[i].cost;
}
}
returnret;
}

/**//**
*theprimalgorithmofmst(minimumcostspanningtree)
*MGraphg:thegraph
*charstart:thestartpoint
*/
voidmst_prim(MGraphg,charstart)...{
mst_prim_closedge*closedge=
(mst_prim_closedge*)malloc(sizeof(mst_prim_closedge)*g.vexnum);
//gettheindexofstart
intindex=locate(g,start);
//inittheclosestedgearray
inti=0;
for(;i<g.vexnum;i++)...{
closedge[i].parent=index;
closedge[i].cost=g.arcs[index][i].adj;
}
//choosethenextn-1vertex
printf("nowthemstis: ");
intj=0;
for(i=1;i<g.vexnum;i++)...{
j=minimum(closedge,g.vexnum);
printf("%c,%c,%d ",
g.vexs[closedge[j].parent],g.vexs[j],closedge[j].cost);
//jjointheU
closedge[j].cost=0;
//updatetheclosedge
for(intk=0;k<g.vexnum;k++)...{
if(g.arcs[j][k].adj>0&&
g.arcs[j][k].adj<closedge[k].cost)...{
closedge[k].cost=g.arcs[j][k].adj;
closedge[k].parent=j;
}
}
}
}

voidmain()...{
MGraphg;
createGragh(g);
charstart;
printf("inputthestartpointofmst: ");
scanf("%c",&start);
mst_prim(g,start);
}
程序的执行结果为:
pleaseinputthetypeofgraph:
3
inputthenumberofvertex:
6
inputthenameofvertex:
a
b
c
d
e
f
nowconstructingthematrixofgraph...
06151000010000
60510000310000
150564
51000050100002
10000361000006
10000100004260
inputthestartpointofmst:
a
nowthemstis:
a,c,1
c,f,4
f,d,2
c,b,5
b,e,3
Pressanykeytocontinue
算法的复杂度:从函数mst_prim()可知,时间复杂度为O(n*n),适用于求边稠密的network的mst。
(2)Kruskal
时间复杂度为O(e*log(e)),适用于求边稀疏的network的mst。
算法思想:“等价类,并查集,边排序,选小边”。
代码如下,头文件添加:

typedefstruct...{
intv1;
intv2;
intcost;
intused;
}mst_kruskal_edge;
源文件添加:
//gettheclassofi
intfindparent(int*parent,inti)...{
while(parent[i]!=-1)...{
i=parent[i];
}
returni;
}
//getthesmallestedgethathasnotused
intgetMin(mst_kruskal_edge*edge,intnum)...{
intcost=INFINITY,index=-1;
for(inti=0;i<num;i++)...{
if(edge[i].used==0&&edge[i].cost<cost)...{
cost=edge[i].cost;
index=i;
}
}
returnindex;
}

/**//**
*thekruskalofmst
*/
voidmst_kruskal(MGraphg)...{
//firstconstructtheedgearray
mst_kruskal_edge*edge=(mst_kruskal_edge*)
malloc(sizeof(mst_kruskal_edge)*g.vexnum/2*(g.vexnum-1));
inti,j,k=0;
for(i=0;i<g.vexnum;i++)...{
for(j=i+1;j<g.vexnum;j++)...{
if(g.arcs[i][j].adj>0&&g.arcs[i][j].adj!=INFINITY)...{
edge[k].v1=i;
edge[k].v2=j;
edge[k].cost=g.arcs[i][j].adj;
//thisedgeisnotused
edge[k].used=0;
k++;
}
}
}
printf("thenumofedgeis:%d ",k);
//theparentarray,representtheclassofthevertice
int*parent=(int*)malloc(sizeof(int)*g.vexnum);
//inititwith-1
for(i=0;i<g.vexnum;i++)...{
parent[i]=-1;
}
//constructthemst
printf("nowconstructingthemst... ");
for(i=0;i<k;i++)...{
intindex=getMin(edge,k);
if(index!=-1)...{
intp1=findparent(parent,edge[index].v1);
intp2=findparent(parent,edge[index].v2);
if(p1!=p2)...{
printf("%c,%c,%d ",
g.vexs[edge[index].v1],g.vexs[edge[index].v2],edge[index].cost);
parent[p2]=p1;
}
edge[index].used=1;
}else...{
break;
}
}
}

voidmain()...{
MGraphg;
createGragh(g);

/**//*
charstart;
printf("inputthestartpointofmst: ");
scanf("%c",&start);
mst_prim(g,start);
*/
mst_kruskal(g);
}
程序的执行结果为:
pleaseinputthetypeofgraph:
3
inputthenumberofvertex:
6
inputthenameofvertex:
a
b
c
d
e
f
nowconstructingthematrixofgraph...
06151000010000
60510000310000
150564
51000050100002
10000361000006
10000100004260
thenumofedgeis:10
nowconstructingthemst...
a,c,1
d,f,2
b,e,3
c,f,4
b,c,5
Pressanykeytocontinue
说明:kruskal至多对e条边各扫描一次,上面的查找算法的复杂度是O(e),所以实现的kruskal的复杂度是O(e*e)。但是如果使用堆排序,每次的查找复杂度可以变成O(log(e))(第一次需要O(e)来建立堆),从而Kruskal的复杂度是O(e * log(e))。

被折叠的 条评论
为什么被折叠?



