收藏 分销(赏)

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

上传人:仙人****88 文档编号:12012416 上传时间:2025-08-27 格式:DOCX 页数:21 大小:336.07KB 下载积分:10 金币
下载 相关 举报
数据结构最小生成树课程设计.docx_第1页
第1页 / 共21页
数据结构最小生成树课程设计.docx_第2页
第2页 / 共21页


点击查看更多>>
资源描述
目录 一、课题描述: 2 二、需求分析 3 三、总体结构设计 4 四、各子模块设计 5 五、编程设计 8 六、测试结果 12 七、总结 14 八、参考文献 15 附 录 16 一、课题描述: 设计一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权代表公路造价。图中任一对城市都是连通的,用公路把所有城市联系起来,设计可使得工程的总造价最少。 二、需求分析 根据课设题目要求,拟将整体程序分为三大模块。此三个模块相互独立,没有嵌套调用的情况,以下是三个模块的大体分析: 1. 建立一个图,其存储方式可以采用邻接矩阵形式,需要定义两个数组,一个存储城市,一个存储公路,存储公路的数组表明城市间的连通关系和公路的造价;。 2. 利用kruskal算法求城市地图的最小生成树 3. 按父亲结点和子女结点集的形式输出生成树中各条边(公路)以及它们的权值(造价),公路总造价最小值。 三、总体结构设计 功能模块图 无 向 图 的 建 立 最 小 生 成 树 的 求 解 按父 结点 和子 女结 点集 的形 式输 出, 求最 小值, 四、各子模块设计 1.无向图的建立(初始化) printf(“\n请输入城市的信息”) n=1 G->arc[i][j].adj=G->arc[j][i].adj=0 j++ i++ j=1 j<=G->vexnum i<=G->vexnum Int i,j,n,h,m,k i=1 N Y N Y n<=G->vexnum scanf(“%s”,vex[n].name); n++ N Y 2.用kruskal算法求最小生成树 sort(edges,G) i=1 找公路和公路的造价 j++ i++ j=i+1 j<=G->vexnum i<G->vexnum Int i,j,n,m i=1 N Y Y N Y Y i<=G->vexnum parent[i]=0; i++ N Y 3.用冒泡法排序 printf(“\n公路造价排序为:”) i=1 公路造价排序 j++ i++ j=i+1 j<=G->vexnum i<G->vexnum int i,j; i=1 N Y N Y N i<=G->vexnum printf(“<%s,%s> %d\n”,vex…); i++ Y 五、编程设计 存储结构 该函数包含三个结构体,即存储城市、存储公路和存储图的结构体,其结构体分别如下所示: 1.顶点和边的存储表示 用字符串name表示城市信息,num表示城市的序号。 struct node{ char name[10]; int num; }vex[20]; 用整型begin和end表示公路的起点和终点,weight表示公路的造价。 typedef struct { int begin; int end; int weight; }edge; 2.图的邻接矩阵存储表示 用整型adj表示城市间的关系,weight表示公路的造价。 typedef struct { int adj; int weight; }AdjMatrix[MAX][MAX]; 用arc表示邻接矩阵,vexnum和arcnum表示图当前的城市数和公路数。 typedef struct { AdjMatrix arc; int vexnum, arcnum; }MGraph; 时间复杂度0(n^2) 算法描述 该算法是建立一个带权的无向图,并用Kruskal算法求该图的最小生成树,用父结点和子女结点集的形式输出最小生成树。 1.无向带权图的建立 图的存储结构如上所示,;用adj是否为1判断两城市间是否有公路,adj为1时表示有公路,反之没有公路,vexnum和arcnum分别表示城市数和公路数,name和num分别表示城市信息和城市序号,建图的算法如下所示: void CreatGraph(MGraph *G) { int i, j,n,h,m,k; char u[MAX],v[MAX]; printf("请输入公路数和城市数:"); scanf("%d %d",&G->arcnum,&G->vexnum) for (i = 1; i <= G->vexnum; i++)//初始化图 { for ( j = 1; j <= G->vexnum; j++) { G->arc[i][j].adj = G->arc[j][i].adj = 0; } } printf("\n请输入城市的信息:"); for(n=1;n<=G->vexnum;n++) { scanf("%s",vex[n].name); vex[n].num=n; } for ( i = 1; i <= G->arcnum; i++) { printf("\n请输入有公路的2个城市:"); scanf("%s",v); scanf("%s",u); for ( k= 1; k <= G->vexnum; k++) { if(strcmp(v,vex[k].name)==0) {m=vex[k].num;} if(strcmp(u,vex[k].name)==0) {h=vex[k].num;} } G->arc[m][h].adj = G->arc[h][m].adj = 1; getchar(); printf("\n请输入%s与%s之间的公路造价:",vex[m].name, vex[h].name); scanf("%d",&G->arc[m][h].weight); } printf("邻接矩阵为:\n"); for ( i = 1; i <= G->vexnum; i++) { for ( j = 1; j <= G->vexnum; j++) { printf("%d ",G->arc[i][j].adj); } printf("\n"); } } 2. Kruskal算法 克鲁斯卡尔算法:假设连通网N=(V,{E}),则令最小生成树的起始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点自成一个连通分量。在E中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将此边加到T中,否则舍去此边而选择下一条代价最小的边。以此类推,直至T中所有的顶点都在同一连通分量上为止。算法代码如下所示: void MiniSpanTree(MGraph *G) { int i, j, n, m; int k = 1; int parent[M]; edge edges[M]; for ( i = 1; i < G->vexnum; i++) { for (j = i + 1; j <= G->vexnum; j++) { if (G->arc[i][j].adj == 1) { edges[k].begin = i; edges[k].end = j; edges[k].weight = G->arc[i][j].weight; k++; } } } sort(edges, G); for (i = 1; i <= G->arcnum; i++) { parent[i] = 0; } printf("最小生成树为:\n"); for (i = 1; i <= G->arcnum; i++) { n = Find(parent, edges[i].begin); m = Find(parent, edges[i].end); if (n != m) { parent[n] = m; printf("<< %s, %s >> %d\n", vex[edges[i].begin].name, vex[edges[i].end].name, edges[i].weight); Mincost+=edges[i].weight; } } printf("使各城市间公路总造价的最小费用为:Mincost=%d\n",Mincost); } int Find(int *parent, int f) { while ( parent[f] > 0) { f = parent[f]; } return f; } 3.用冒泡法对公路造价按从小到大的顺序排列 void sort(edge edges[] ,MGraph *G) { int i, j; int temp; for ( i = 1; i < G->arcnum; i++) { for ( j = i+1; j <=G->arcnum; j++) { if (edges[i].weight > edges[j].weight) { 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; } } } 六、测试结果 城市间公路及其造价的输出结果 邻接矩阵输出结果 造价排序运行结果 最小生成树的输出结果以及公路总造价最小值 七、总结 经过一周不懈的努力我们终于完成了课程设计。通过这次课程设计,既巩固了以前学过的C语言的知识,体会到C语言超强的逻辑性,能够熟练使用VC++的编译环境,也对这两门课程有了新的认识,他们既有联系,又相互区别,要灵活应用。 利用了课本所学的最小成生树,完成了这一课题,深刻的体会到它的实用性,也发现我们对于C语言和数据结构还有很多地方不知道。程序设计是脑力劳动和体力劳动相结合的,没有平时基础的训练是不会写出高效的算法,今后仍需要努力学习。 课让我尝到了学习的快乐,成功的喜悦。要完成一项任务或把东西学好就必须有足够的信心,持久的耐心,有面对困难无所畏惧的精神,这对我日后的学习和生活产生了深远一个影响。 八、参考文献 [1] 严蔚敏,吴伟民.数据结构[M].北京:清华大学出版社,2007. [2] 张长海,陈娟.C程序设计[M].北京:高等教育出版社,2004. [3] 谭浩强.C程序设计[M].北京:清华大学出版社,2005. [4]陈杰.计算机专业课程设计中的需求分析[J].集美大学学报,2009. [5]高一凡. 数据结构算法实现及解析[M ]. 西安:西安电子科技大学出版社, 2002. 附 录 程序代码 #include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> #define M 20 #define MAX 20 struct node{ char name[10]; int num; }vex[20]; typedef struct { int begin; int end; int weight; }edge; typedef struct { int adj; int weight; }AdjMatrix[MAX][MAX]; typedef struct { AdjMatrix arc; int vexnum, arcnum; }MGraph; void CreatGraph(MGraph *); void MiniSpanTree(MGraph *); void sort(edge* ,MGraph *); int Find(int *, int ); void CreatGraph(MGraph *G) { int i, j,n,h,m,k; char u[MAX],v[MAX]; printf("请输入公路数和城市数:"); scanf("%d %d",&G->arcnum,&G->vexnum); for (i = 1; i <= G->vexnum; i++)//初始化图 { for ( j = 1; j <= G->vexnum; j++) { G->arc[i][j].adj = G->arc[j][i].adj = 0; } } printf("\n请输入城市的信息:"); for(n=1;n<=G->vexnum;n++) { scanf("%s",vex[n].name); vex[n].num=n; } for ( i = 1; i <= G->arcnum; i++) { printf("\n请输入有公路的2个城市:"); scanf("%s",v); scanf("%s",u); for ( k= 1; k <= G->vexnum; k++) { if(strcmp(v,vex[k].name)==0) {m=vex[k].num;} if(strcmp(u,vex[k].name)==0) {h=vex[k].num;} } G->arc[m][h].adj = G->arc[h][m].adj = 1; getchar(); printf("\n请输入%s与%s之间的公路造价:",vex[m].name, vex[h].name); scanf("%d",&G->arc[m][h].weight); } printf("邻接矩阵为:\n"); for ( i = 1; i <= G->vexnum; i++) { for ( j = 1; j <= G->vexnum; j++) { printf("%d ",G->arc[i][j].adj); } printf("\n"); } } void sort(edge edges[] ,MGraph *G)//对公路造价进行排序 { int i, j; int temp; for ( i = 1; i < G->arcnum; i++) { for ( j = i+1; j <=G->arcnum; j++) { if (edges[i].weight > edges[j].weight) { 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; } } } printf("造价排序之后的为:\n"); for (i = 1; i <=G->arcnum; i++) { printf("<< %s, %s >> %d\n", vex[edges[i].begin].name, vex[edges[i].end].name, edges[i].weight); } } void MiniSpanTree(MGraph *G) { int i, j, n, m,Mincost=0; int k = 1; int parent[M]; edge edges[M]; for ( i = 1; i < G->vexnum; i++) { for (j = i + 1; j <= G->vexnum; j++) { if (G->arc[i][j].adj == 1) { edges[k].begin = i; edges[k].end = j; edges[k].weight = G->arc[i][j].weight; k++; } } } sort(edges, G); for (i = 1; i <= G->arcnum; i++) { parent[i] = 0; //初始化,没有边关系。 } printf("最小生成树为:\n"); for (i = 1; i <= G->arcnum; i++) { n = Find(parent, edges[i].begin); m = Find(parent, edges[i].end); if (n != m) { parent[n] = m; printf("<< %s, %s >> %d\n", vex[edges[i].begin].name, vex[edges[i].end].name, edges[i].weight); Mincost+=edges[i].weight; } } printf("使各城市间公路总造价的最小费用为:Mincost=%d\n",Mincost); } int Find(int *parent, int f) { while ( parent[f] > 0) { f = parent[f]; } return f; } void main() { MGraph *G; char p; G = (MGraph*)malloc(sizeof(MGraph)); CreatGraph(G); MiniSpanTree(G); scanf("%s",&p); if(p=='out'){ exit(0); } } 21
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服