最小生成树的应用数据结构课程设计.docx

上传人:b****6 文档编号:4339012 上传时间:2022-11-29 格式:DOCX 页数:18 大小:253.35KB
下载 相关 举报
最小生成树的应用数据结构课程设计.docx_第1页
第1页 / 共18页
最小生成树的应用数据结构课程设计.docx_第2页
第2页 / 共18页
最小生成树的应用数据结构课程设计.docx_第3页
第3页 / 共18页
最小生成树的应用数据结构课程设计.docx_第4页
第4页 / 共18页
最小生成树的应用数据结构课程设计.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

最小生成树的应用数据结构课程设计.docx

《最小生成树的应用数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《最小生成树的应用数据结构课程设计.docx(18页珍藏版)》请在冰豆网上搜索。

最小生成树的应用数据结构课程设计.docx

最小生成树的应用数据结构课程设计

 

课程设计(论文)

 

题目名称最小生成树的应用

课程名称数据结构课程设计

学生姓名

学号

系、专业信息工程系、通信工程

指导教师

 

2012年12月23日

摘要

求一个网的最小生成树,即以最低的经济建设n个城市之间的通信网,利用普里姆算法和克鲁斯卡尔算法求这个网的最小生成树。

关键词:

网的最小生成树;Kruskal算法;Prim算法;边和权值。

 

目录

1问题描述1

2需求分析1

3概要设计1

3.1抽象数据类型定义1

3.2模块划分3

4详细设计5

4.1数据类型的定义5

4.2主要模块的算法描述5

5测试分析13

6课程设计总结13

参考文献16

附录(源程序清单)17

1问题描述

若要在n个城市之间建设通信网络,只需要架设n-1条线路即可。

如何以最低的经济建设这个通信网,是一个网的最小生成树。

2需求分析

(1).可以用连通网来表示n个城市间可能设置的通信网络,其中网的顶点表示城市,边表示两城市之间的路线,边的权值表示相应的费用。

对于n个顶点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网。

现在,我们要选择这样一棵生成树,它使总的费用最少,这棵树就是最小生成树。

一棵生成树的费用就是树上各边的费用之和。

(2).本程序的目的是要建设一个最经济的通信网,根据用户输入的网,输出相应的最小生成树。

在这里城市以及两城市之间的费用都用整型数来代替。

利用克鲁斯卡尔算法和普利姆算法实现。

3概要设计

3.1抽象数据类型定义1.ADTGraph

{数据对象V:

v是具有相同特性的数据元素的集合,称为顶点集。

数据关系R:

R={VR}

VR={|v,w属于v且p(v,w),(v,w)表示从v到w的弧,谓词p(v,w)定义了弧的意义或信息}

基本操作:

(1)CreatGraph(&G,V,VR);

初始条件:

V是图的顶点集,VR是图中弧的集合。

操作结果:

按V和VR的定义构造图G。

(2)LocateVex(G,u);

初始条件:

图G存在,u和G中顶点有相同的特征。

操作结果:

若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息。

(3)DestoryGraph(&u);

初始条件:

图G存在。

操作结果:

销毁图G。

(4)GetVex(G,v);

初始条件:

图G存在,v是图中某个顶点。

操作结果:

返回v的值。

(5)NextAdjVex(G,v,w);

初始条件:

图G存在,v是图中某个顶点,w是v的邻接顶点。

操作结果:

返回v的(相对于w的)下一个邻接顶点。

若w是v的最后一个邻接点,则返回“空”。

(6)BFSTraverse(G,Visit());

初始条件:

图G存在,Visit是顶点的应用函数。

操作结果:

对图进行广度优先遍历。

在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

}

2.存储结构

Typedefstruct

{

intadj;

intweight;

}AdjMatrix[MAX][MAX];

Typedefstruct

{

djMatrixarc;

intvexnum,arcnum;

}MGraph;

3.2模块划分

本程序包括五个模块:

(1)主函数模块

(2)邻接矩阵定义模块代码

typedefstructArcCell{

intadj;char*info;

}ArcCell,AdjMatrix[20][20];

typedefstruct{

charvexs[20];AdjMatrixarcs;

intvexnum,arcnum;

}MGraph_L;

intlocalvex(MGraph_LG,charv)

{inti=0;while(G.vexs[i]!

=v){++i;}returni;}

(3)创建链接矩阵模块代码

intcreatMGraph_L(MGraph_L&G)

{charv1,v2;inti,j,w;

cout<<"…创建无向图(城市分布图)…"<

(46)不包括“()”"<

cin>>G.vexnum>>G.arcnum;

for(i=0;i!

=G.vexnum;++i)

{cout<<"输入顶点(城市)"<>G.vexs[i];}

for(i=0;i!

=G.vexnum;++i)

for(j=0;j!

=G.vexnum;++j)

{G.arcs[i][j].adj=int_max;G.arcs[i][j].info=NULL;}

for(intk=0;k!

=G.arcnum;++k)

{cout<<"输入一条边依附的顶点(城市)和权(距离):

(ab3)不包括“()”"<>v1>>v2>>w;

i=localvex(G,v1);j=localvex(G,v2);

G.arcs[i][j].adj=w;G.arcs[j][i].adj=w;}

cout<<"图G邻接矩阵创建成功!

"<

(4)最小生成树Prim算法及代价模块代码

(5)最小生成树kruskal算法及代价模块代码

4详细设计

4.1数据类型的定义

(1)树类型

#defineMAXVALUE100

#defineMAXLEAF50

#defineMAXNODEMAXLEAF*2-1;

(2)图类型

typedefstructnode{

intadjvex;

intw;

structnode*nextedge;

}edgenode;

typedefstruct{

chardata;

intid;

edgenode*firstedge;

}vexnode;

 

4.2主要模块的算法描述

(1)主函数

algraphgra;MGraph_LG;inti,d,g[20][20];

chara='a';d=creatMGraph_L(G);vnodev;

cout<

若该图为非强连通图(含有多个连通分量)时"<

<<"最小生成树不存在,则显示为非法值"<

cout<<"…………………菜单……………………"<

cout<<"0、显示该图的邻接矩阵……………………"<

cout<<"1、最小生成树PRIM算法及代价…………………"<

ints;chary='y';

while(y='y'){cout<<"请选择菜单:

"<>s;

switch(s){

case0:

cout<<"邻接矩阵显示如下:

"<

case1:

for(i=0;i!

=G.vexnum;++i)

for(intj=0;j!

=G.vexnum;++j)g[i+1][j+1]=G.arcs[i][j].adj;

cout<<"prim:

"<

cout<

y/n:

";cin>>y;if(y=='n')break;}

}

 

 

图4.1流程图

 

(2)最小生成树Prim算法及代价模块代码

intprim(intg[][max],intn){

intlowcost[max],prevex[max];inti,j,k,min;intsum=o;

for(i=2;i<=n;i++){lowcost[i]=g[1][i];prevex[i]=1;}

lowcost[1]=0;for(i=2;i<=n;i++)//形成n-1条边的生成树

{min=inf;k=0;

for(j=2;j<=n;j++)

if((lowcost[j]

=0)){min=lowcost[j];k=j;}

printf("(%d,%d)%d\t",prevex[k]-1,k-1,min);

sum+=min;lowcost[k]=0;

for(j=2;j<=n;j++)if(g[k][j]

{lowcost[j]=g[k][j];prevex[j]=k;}

printf("\n");}

cout<<"最少生成树的代价:

";cout<

 

 

 

输入起点st

 

 

结束

图4.2Prim算法流程图

 

(3)最小生成树kruskal算法及代价模块代码

voidMiniSpanTree(MGraphA*D)//生成最小生成树

{inti,j,n,m,SUM=0;intk=1;

intparent[M];edgeedges[M];

for(i=1;ivexnum;i++)

{for(j=i+1;j<=D->vexnum;j++){if(D->arc[i][j].adj==1)

{edges[k].begin=i;edges[k].end=j;

edges[k].weight=D->arc[i][j].weight;k++;}

}

}

sort(edges,D);

for(i=1;i<=D->arcnum;i++)

{parent[i]=0;}

printf("最小生成树为:

\n");

for(i=1;i<=D->arcnum;i++)//核心部分

{n=Find(parent,edges[i].begin);m=Find(parent,edges[i].end);

if(n!

=m){parent[n]=m;

printf("<<%d,%d>>%d\n",edges[i].begin,edges[i].end,edges[i].weight);

SUM=SUM+edges[i].weight;}

}

 

图4.3Kruskal算法流程图

5测试分析

测试数据及结果如下:

图5.1创建邻接矩阵

 

图5.2Prim算法求解

图5.3Kruskal算法求解

 

6课程设计总结

从这次给我的课程设计任务中我深刻地体会到了编程并非易事。

任何事情并不是想我们想的那样简单和容易。

只有扎扎时时的学习知识才能解决实际生活中的实际问题。

从这次课设中也让我明白以后要多了解相关知识,更多的做一些实践动手活动,将知识运用到实际问题中。

同时,增加自己的动手能力,这样才能便于我们更好的解决问题。

为今后打下好的基础。

实验过程中,我遇到了很多问题,一开始就要建一个图,然后利用kruskal算法解决问题,这个题目是一个十分联系实际的题目,使我更加扎实的掌握了有关数据结构方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。

实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。

过而能改,善莫大焉。

在课程设计过程中,我不断发现错误,不断改正,不断领悟,不断获取。

最终的调试运行环节,本身就是在践行“过而能改,善莫大焉”的知行观。

这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于迎刃而解。

当我完成课程设计后,我感到很欣喜。

能完成让我感到什么叫做编程的快乐,什么叫做乐趣。

也让明白要想把通信工程这门专业学好必须持之以恒地努力下去。

参考文献

[1]黄同成,黄俊民,董建寅.数据结构[M].北京:

中国电力出版社,2008

[2]董建寅,黄俊民,黄同成.数据结构实验指导与题解[M].北京:

中国电力出版社,2008

[3]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:

清华大学出版社,2002

[4]刘振鹏,张晓莉,郝杰.数据结构[M].北京:

中国铁道出版社,2003

附录(源程序清单)

#include

#include

usingnamespacestd;

#defineint_max10000

#defineinf9999

#definemax20

#defineMAX20

#defineM20

typedefstructArcCell

{intadj;char*info;

}ArcCell,AdjMatrix[20][20];

typedefstruct

{charvexs[20];AdjMatrixarcs;intvexnum,arcnum;

}MGraph;

intlocalvex(MGraphG,charv)

{inti=0;while(G.vexs[i]!

=v){++i;}returni;}

voidljjzprint(MGraphG)

{inti,j,n=0;printf("建立的邻接矩阵如下:

\n");printf("\n");

printf("_____________________________________________\n");

for(i=0;i!

=G.vexnum;i++)

{for(j=0;j!

=G.vexnum;j++)

{if(j==0)printf("");

printf("%d",G.arcs[i][j].adj);printf("");n++;

if(n==G.vexnum){printf("\n");n=0;}}

}

printf("______________________________________________\n");}

intcreatMGraph(MGraph&G)

{charv1,v2;inti,j,w;

printf("建立邻接矩阵:

\n");

printf("请输入图G顶点(城市)和弧(边)的个数:

");

scanf("%d",&G.vexnum);scanf("%d",&G.arcnum);printf("输入所有顶点:

");

for(i=0;i>G.vexs[i];}

for(i=0;i

for(j=0;j

printf("输入所有边及依附的顶点(城市)和权(距离):

\n");

for(intk=0;k

{cin>>v1>>v2>>w;i=localvex(G,v1);j=localvex(G,v2);

G.arcs[i][j].adj=w;G.arcs[j][i].adj=w;}

ljjzprint(G);

printf("图G邻接矩阵创建成功!

\n");

returnG.vexnum;}intvisited[max];intwe;

typedefstructarcnode

{intadjvex;structarcnode*nextarc;char*info;}arcnode;

typedefstructvnode

{chardata;arcnode*firstarc;}vnode,adjlist;

typedefstruct//图的定义

{adjlistvertices[max];intvexnum,arcnum;intkind;}algraph;

intprim(intg[][max],intn)//最小生成树PRIM算法

{intlowcost[max],prevex[max];inti,j,k,min;intsum=0;

for(i=2;i<=n;i++){lowcost[i]=g[1][i];prevex[i]=1;}

lowcost[1]=0;

for(i=2;i<=n;i++){min=inf;k=0;

for(j=2;j<=n;j++)

if((lowcost[j]

=0)){min=lowcost[j];k=j;}

printf("(%d,%d)%d\t",prevex[k]-1,k-1,min);sum+=min;lowcost[k]=0;

for(j=2;j<=n;j++)if(g[k][j]

printf("\n");}

cout<<"最少生成树的代价:

";cout<

typedefstruct{intbegin;intend;intweight;}edge;

typedefstruct{intadj;intweight;}Adj[MAX][MAX];

typedefstruct{Adjarc;intvexnum,arcnum;}MGraphA;

voidCreatGraph(MGraphA*);//函数申明

voidsort(edge*,MGraphA*);

voidMiniSpanTree(MGraphA*);

intFind(int*,int);

voidSwapn(edge*,int,int);

voidCreatGraph(MGraphA*D)//构件图

{inti,j,n,m;

printf("请输入边数和顶点数:

");

scanf("%d%d",&D->arcnum,&D->vexnum);

for(i=1;i<=D->vexnum;i++)//初始化图

{for(j=1;j<=D->vexnum;j++){D->arc[i][j].adj=D->arc[j][i].adj=0;}}

for(i=1;i<=D->arcnum;i++)//输入边和权值

{printf("\n请输入有边的2个顶点");scanf("%d%d",&n,&m);

while(n<0||n>D->vexnum||m<0||n>D->vexnum)

{printf("输入的数字不符合要求请重新输入:

");scanf("%d%d",&n,&m);}

D->arc[n][m].adj=D->arc[m][n].adj=1;getchar();

printf("\n请输入%d与%d之间的权值:

",n,m);scanf("%d",&D->arc[n][m].weight);}

printf("邻接矩阵为:

\n");

for(i=1;i<=D->vexnum;i++)

{for(j=1;j<=D->vexnum;j++)

{printf("%d",D->arc[i][j].adj);}printf("\n");}

}

voidsort(edgeedges[],MGraphA*D)//对权值进行排序

{inti,j;

for(i=1;iarcnum;i++)

{for(j=i+1;j<=D->arcnum;j++)

{if(edges[i].weight>edges[j].weight){Swapn(edges,i,j);}}

}

printf("权排序之后的为:

\n");

for(i=1;iarcnum;i++)

{printf("<<%d,%d>>%d\n",edges[i].begin,edges[i].end,edges[i].weight);}

}

voidSwapn(edge*edges,inti,intj)//交换权值以及头和尾

{inttemp;temp=edges[i].begin;edges[i].begin=edges[j].begin;

edges[j].begin=temp;temp=edges[i].end;

edges[i].end=edges[j].end;edges[j].end=temp;

temp=edges[i].weight;edges[i].weight=edges[j].weight;

edges[j].weight=temp;}

voidMiniSpanTree(MGraphA*D)//生成最小生成树

{inti,j,n,m,SUM=0;intk=1;

intparent[M];edgeedges[M];

for(i=1;ivexnum;i++)

{for(j=i+1;j<=D->vexnum;j++)

{if(D->arc[i][j].adj==1){edges[k].begin=i;edges[k].end=j;edges[k].weight=D->arc[i][j].weight;k++;}}

}

sort(edges,D);

for(i=1;i<=D->arcnum;i++)

{parent[i]=0;}printf("最小生成树为:

\n");

for(i=1;i<=D->arcnum;i++)//核心部分

{n=Find(parent,edges[i].begin);m=Find(parent,edges[i].end);

if(n!

=m){parent[n]=m;printf("<<%d,%d>>%d\n",

edges[i].begin,edges[i].end,edges[i].weight);SUM=SUM+edges[i].weight;}

}cout<<"最少生成树的代价:

";cout<

intFind(int*parent,intf)//找尾

{while

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 初中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1