石大《数据结构课程设计》.docx
- 文档编号:1730200
- 上传时间:2022-10-23
- 格式:DOCX
- 页数:11
- 大小:103.13KB
石大《数据结构课程设计》.docx
《石大《数据结构课程设计》.docx》由会员分享,可在线阅读,更多相关《石大《数据结构课程设计》.docx(11页珍藏版)》请在冰豆网上搜索。
石大《数据结构课程设计》
中国石油大学(北京)
远程教育学院
《数据结构》课程设计报告
课程设计题目
知金教育北京数字化学习中心
学生姓名
李龙超
学号
101173
专业班级
2020年1月
题目要求:
设计一个稀疏矩阵计算器,实现两个稀疏矩阵的加法、减法、乘法以及矩阵的转置运算。
采用菜单为应用程序的界面,用户通过对菜单进行选择,分别实现矩阵的相加、相减、相乘以及矩阵转速运算。
1需求分析
1.至少包含10个城市;
2.城市数n由键盘录入;
3.城市坐标由随机函数产生小于100的整数;
4.输出生成树中各条边以及它们的权值;
5.利用克鲁斯卡尔算法求网的最小生成树。
6.实现并查集。
以此表示构造生成树过程中的连通分量。
7.以文本形式输出生成树中各条边以及他们的权值。
2概要设计
1、边集数组的类型定义:
typedefstruct
{
intx,y;
intw;
}edge;
x表示起点,y表示终点,w为权值。
2、并查集功能的实现由以下函数实现:
Make_Set(intx)初始化集合;
Find_Set(intx)查找x元素所在的集合,回溯时压缩路径;
Union(intx,inty,intw)合并x,y所在的集合。
克鲁斯卡尔算法的实现
该算法的实现位于主函数中:
qsort(e,n,sizeof(edge),cmp);//将边排序
printf("最小生成树的各条边及权值为:
\n");
for(i=0;i { x=Find_Set(e[i].x); y=Find_Set(e[i].y); if(x! =y) { printf("%c-%c: %d\n",e[i].x+'A',e[i].y+'A',e[i].w); Union(x,y,e[i].w); } } 4、设计中还包含以下函数: /*比较函数,按权值(相同则按x坐标)非降序排序*/ intcmp(constvoid*a,constvoid*b) { if((*(edge*)a).w==(*(edge*)b).w) { return(*(edge*)a).x-(*(edge*)b).x; } return(*(edge*)a).w-(*(edge*)b).w; } 5、主程序的流程图 3详细设计 #include #include #include"time.h" #defineMAX435 /*定义边(x,y),权为w*/ typedefstruct { intx,y; intw; }edge; edgee[MAX]; /*rank[x]表示x的秩*/ intrank[MAX]; /*father[x]表示x的父节点*/ intfather[MAX]; /*比较函数,按权值(相同则按x坐标)非降序排序*/ intcmp(constvoid*a,constvoid*b) { if((*(edge*)a).w==(*(edge*)b).w) { return(*(edge*)a).x-(*(edge*)b).x; } return(*(edge*)a).w-(*(edge*)b).w; } /*初始化集合*/ voidMake_Set(intx) { father[x]=x; rank[x]=0; } /*查找x元素所在的集合,回溯时压缩路径*/ intFind_Set(intx) { while(father[x]) { x=father[x]; } returnx; } /*合并x,y所在的集合*/ voidUnion(intx,inty,intw) { if(x==y)return; /*将秩较小的树连接到秩较大的树后*/ if(rank[x]>rank[y]) { father[y]=x; } else { if(rank[x]==rank[y]) { rank[y]++; } father[x]=y; } } /*主函数*/ intmain() { printf("*最小生成树问题: \n"); inti,n,h,k=0; intx,y; charchx,chy; printf("\n人为输入权值请输入1,随机生成权值请输入0: \n"); scanf("%d",&k); if(k==1) { /*读取边的数目*/ printf("请输入边的条数(小于436): \n"); scanf("%d",&n); getchar(); /*读取边信息并初始化集合*/ printf("请输入边的信息(起点,终点,权值(<100))分别用空格隔开: \n"); for(i=0;i { scanf("%c%c%d",&chx,&chy,&e[i].w); getchar(); e[i].x=chx-'A'; e[i].y=chy-'A'; Make_Set(i); } } else{ printf("请输入顶点数(<=30): \n"); scanf("%d",&h); getchar(); srand((unsigned)time(NULL)); n=(h-1)*h/2;chx=49;chy=50; for(i=0;i { e[i].w=rand()%100+1; e[i].x=chx-'A';if(chy==h+48)chx++; e[i].y=(chy++)-'A'; if(chy==h+49)chy=chx+1; Make_Set(i); } printf("随机生成的各条边及权值为: \n"); for(i=0;i { printf("%c-%c: %d\n",e[i].x+'A',e[i].y+'A',e[i].w); } } /*将边排序*/ qsort(e,n,sizeof(edge),cmp); printf("最小生成树的各条边及权值为: \n"); for(i=0;i { x=Find_Set(e[i].x); y=Find_Set(e[i].y); if(x! =y) { printf("%c-%c: %d\n",e[i].x+'A',e[i].y+'A',e[i].w); Union(x,y,e[i].w); } } return0; } 1、边集数组的类型定义: typedefstruct { intx,y; intw; }edge; x表示起点,y表示终点,w为权值。 2、并查集功能的实现由以下函数实现: Make_Set(intx)初始化集合; Find_Set(intx)查找x元素所在的集合,回溯时压缩路径; Union(intx,inty,intw)合并x,y所在的集合。 3、克鲁斯卡尔算法的实现 该算法的实现位于主函数中: qsort(e,n,sizeof(edge),cmp);//将边排序 printf("最小生成树的各条边及权值为: \n"); for(i=0;i { x=Find_Set(e[i].x); y=Find_Set(e[i].y); if(x! =y) { printf("%c-%c: %d\n",e[i].x+'A',e[i].y+'A',e[i].w); Union(x,y,e[i].w); } } 4、设计中还包含以下函数: (1)/*比较函数,按权值(相同则按x坐标)非降序排序*/ intcmp(constvoid*a,constvoid*b) { if((*(edge*)a).w==(*(edge*)b).w) { return(*(edge*)a).x-(*(edge*)b).x; } return(*(edge*)a).w-(*(edge*)b).w; } (2)快排函数qsort,包含在stdlib.h头文件里 qsort(e,n,sizeof(edge),cmp); (3)C语言提供的随机数函数srand(unsignedintseed); 使用随机数函数如下: srand((unsigned)time(NULL)); for(i=0;i { e[i].w=rand()%100+1; e[i].x=chx-'A';if(chy==h+48)chx++; e[i].y=(chy++)-'A'; if(chy==h+49)chy=chx+1; Make_Set(i); } 输出1~100之间的随机数,使用rand()%100+1。 4程序测试 1、打开界面: (1)人为输入权值,输入1,回车: 输入7,回车: 输入边的信息及结果如下: (2)随机生成权值,输入0: 输入顶点数5,结果如下: 5感想与体会 通过本次课程设计,我学会了利用克鲁斯卡尔算法求最小生成树。 另外学会了利用随机函数产生随机数,以及课本没有提到的边集数组的定义和使用。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构课程设计 数据结构 课程设计