`
gaofen100
  • 浏览: 1191715 次
文章分类
社区版块
存档分类
最新评论

数据结构 图 最小生成树

 
阅读更多

(1)Prim

算法如下,头文件:

#defineINFINITY10000
#defineMAX_VERTEX_NUM20

typedef
intInfoType;
typedef
charVertexType;
typedef
intVRType;

typedef
enum...{DG,DN,UDG,UDN}GraphKind;

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

typedef
struct...{
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

typedef
struct...{
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
Pressanykey
tocontinue

算法的复杂度:从函数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
thenumofedge
is:10
nowconstructingthemst...
a,c,
1
d,f,
2
b,e,
3
c,f,
4
b,c,
5
Pressanykeyto
continue

说明:kruskal至多对e条边各扫描一次,上面的查找算法的复杂度是O(e),所以实现的kruskal的复杂度是O(e*e)。但是如果使用堆排序,每次的查找复杂度可以变成O(log(e))(第一次需要O(e)来建立堆),从而Kruskal的复杂度是O(e * log(e))。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics