Loading... # 记录C语言的数据结构课程设计详情 **<span style='color:#DC143C'>这个课程设计已经被评为优秀!</span>** --- <div class="panel panel-default box-shadow-wrap-lg goal-panel"> <div class="panel-heading"> C语言的数据结构课程设计时间线 </div> <div class="padder-md wrapper"> <div class="streamline b-l m-b"><div class="sl-item b- b-l"> <div class="m-l"> <div class="text-muted">2020-6-22</div> <p>明确任务为校园导航问题</p> </div> </div><div class="bg-light wrapper-sm m-l-n m-r-n m-b r r-2x">撰写程序源码</div><div class="bg-light wrapper-sm m-l-n m-r-n m-b r r-2x">验算程序</div><div class="bg-light wrapper-sm m-l-n m-r-n m-b r r-2x">绘制出N-S图</div><div class="sl-item b-black b-l"> <div class="m-l"> <div class="text-muted">2021-7-2</div> <p>完成课设任务书及说明书</p> </div> </div><div class="sl-item b-warning b-l"> <div class="m-l"> <div class="text-muted">2021-7-3</div> <p>答辩完成</p> </div> </div></div></div></div> * 课程设计任务书:[校园导航问题.doc](https://www.xuegao-tzx.top/usr/uploads/2021/08/1571656960.doc) --- ## 设计目的 (1)了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力; (2)初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; (3)提高综合运用所学的理论知识和方法独立分析和解决问题的能力; (4)训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法作风。 --- ## 已实现功能 (1)设计学校的平面图(已包括15个不同的场所)。 (2)每两个场所间有不同的路径,且路长也不同(图形结构可以通过键盘输入数据后采用创建图的算法生成图形); (3)可以展示已输入的地点信息 (4)可以展示已输入的道路信息 (5)可以修改,删除已输入的地点信息 (6)可以修改,删除已输入的道路信息 (7)提供起始点能自动找出从此地点到达其它地点的最短路径 (8)提供起始点与终点能自动找出从任意场所到达另一场所的最短路径 --- ## 本设计采用的数据结构 <div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div> ------- ## 系统功能模块结构图及函数说明 ### 系统功能模块结构图  ### 主函数 ``` int main(){ create(); while(1){ system("cls"); jiemian(); } return 0;/*永真循环为了实现选择后返回主菜单*/ } ```  ### 设置输出界面的颜色的函数 ``` void setColor(unsigned short ForeColor,unsigned short BackGroundColor){ HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, ForeColor + BackGroundColor * 0x10); }/*设置输出界面的颜色的函数*/ ``` ### 菜单界面的函数 ``` void jiemian(){ setColor(9, 15); system("cls"); int n=0; printf("\n\n 欢迎光临NUC主校区校园导航中心! \n\n"); printf("\n 请选择您要进行的操作: \n"); printf("\n 1.查看已有地点 \n"); printf(" 2.查看已有道路 \n"); printf(" 3.修改已有地点 \n"); printf(" 4.增加新的地点 \n"); printf(" 5.删除现有地点 \n"); printf(" 6.增加新的道路 \n"); printf(" 7.删除现有道路 \n"); printf(" 8.查找当前地点到其它地点的最短路径 \n"); printf(" 9.查找任一的两个地点之间的最短路径 \n"); printf(" 10.退出系统! \n"); printf("\n 注意:请务必输入整型数字! \n\n"); scanf("%d",&n); getchar(); switch(n){ case 1: Introduce(); break; case 2: Showlj(); break; case 3: Changejd(); break; case 4: Increasejd(); break; case 5: Deletejd(); break; case 6: Increaselj(); break; case 7: Deletelj(); break; case 8: Zdlj(); break; case 9: Zdlj_2(); break; case 10: system("cls"); printf("退出成功!\n"); exit(0); default: printf("您的输入有误,请重新输入!\n"); system("pause"); break; } }/*调用setColor函数来实现终端显示颜色的更改,用switch语句用来选择相应功能*/ ```  ### 创建地图的函数 ``` void create() { M.v=XX;//XX为已录入的地点数量 M.e=xxx;//xxx为已录入地点的道路的数量 int i,j,k; for(i=0; i<JD; i++){ for(j=0; j<JD; j++){ M.edges[i][j]=INF; } }/*先创建默认边为无穷(长度为:INF)的地图*/ strcpy(M.vexs[0].name,"地点名字"); strcpy(M.vexs[0].xinxi,"地点介绍"); M.edges[0][1]=M.edges[1][0]=230;/*将0号节点到1号节点的路径赋值为230,因为是无向图,所以1号顶点到0号顶点的路径长度也应赋值为230*/ } ``` ### 查看已有地点子函数 ``` void Introduce(){ system("cls"); int n=0; if(M.v==0){ printf("本导航图暂时无地点!\n\n"); system("pause"); return ; } showjd(); printf("\n请输入你要查看的地点代号:\n"); while(1){ scanf("%d",&n); if(n<1||n>M.v) printf("您的输入有误,请重新输入!\n"); else break; } printf("%s:",M.vexs[n-1].name); printf("%s\n",M.vexs[n-1].xinxi); system("pause"); }/*先通过当前节点数的数值来判断是否有地点可以查看,再判断地点代号是否符合范围,最后都符合后利用数组信息调出来展示相应信息*/ ```  ### 展示已有地点子函数 ``` void showjd(){ if(M.v==0){ printf(" 当前导航图中没有地点!\n\n"); system("pause"); return ; } if(M.v>0){ printf(" NUC导航图当前有如下地点: \n\n"); for(int i=0; i<M.v; i++){ printf("\t\t <%d>%s \n",i+1,M.vexs[i].name); } } }/*展示图中所有节点*/ ```  ### 查看已有道路子函数 ``` void Showlj(){ system("cls"); if(M.e<=0){ printf(" 当前导航图中没有道路!\n\n"); system("pause"); return ; } if(M.e>0){ printf(" NUC导航图当前有如下%d条道路: \n\n",M.e); int a,b; for(a=0; a<M.v; a++){ for(b=0; b<a; b++){ if(M.edges[a][b]!=0){ if(M.edges[a][b]!=INF){ printf("\t 【%s】 <---> 【%s】,距离是%d米 \n",M.vexs[a].name,M.vexs[b].name,M.edges[a][b]); } } } } } system("pause"); }/*先通过当前边数的数值来判断是否有道路可以查看,可以查看时通过2个for循环嵌套来输出构造的二维数组的下三角内容来实现边的长度以及所有无向边不重复的输出*/ ```  ### 修改已有地点子函数 ``` void Changejd(){ system("cls"); int n; if(M.v<=0){ printf("导航图中无地点,无法操作!\n"); system("pause"); return ; } showjd(); printf("请输入您要修改的地点代号:\n"); scanf("%d",&n); while(n<=0||n>M.v){ printf("您的输入有误,请重新输入!\n"); scanf("%d",&n); } char newName[50],newxinxi[1000]; printf("该地点当前的名字是:\n\n【%s】\n\n请输入更改后的名字:\n",M.vexs[n-1].name); scanf("%s",newName); getchar(); printf("该地点当前的介绍为:\n\n%s\n\n请输入更改后新的地点介绍:\n",M.vexs[n-1].xinxi); scanf("%s",newxinxi); getchar(); strcpy(M.vexs[n-1].name,newName); strcpy(M.vexs[n-1].xinxi,newxinxi); printf("\n地点信息修改成功!\n"); system("pause"); }/*先通过当前节点数的数值来判断是否有地点可以更改,再判断地点代号是否符合范围,符合的话,通过字符串复制语句(strcpy)来将更改后的信息写入一维数组中实现修改*/ ```  ### 增加新的地点子函数 ``` void Increasejd(){ system("cls"); int a,d,i,m=0; if(M.v>JD){ printf("地点已达最大上限50个,当前无法添加景点!\n"); system("pause"); return ; } char newName[50],newxinxi[1000]; printf("请输入您要添加的地点名:\n"); scanf("%s",newName); getchar(); printf("请输入【%s】地点的介绍,最多可输入200字:\n",newName); scanf("%s",newxinxi); getchar(); showjd(); printf("请输入新增地点的相邻地点个数:\n"); scanf("%d",&m); while(m<0||m>M.v){ printf("您的输入有误,请重新输入!\n"); scanf("%d",&m); } for(i=0; i<m; i++){ printf("请输入第%d个相邻地点的代号:\n",i+1); scanf("%d",&a); while(a<=0||a>M.v||M.edges[a-1][M.v]!=INF){ if(a<=0||a>M.v) printf("您的输入有误,请重新输入!范围在1~%d之间。\n",M.v); if(M.edges[a-1][M.v]!=INF) printf("请不要输入重复的相邻地点,重新输入:\n"); scanf("%d",&a); } printf("请输入【%s】与【%s】之间的距离:\n",newName,M.vexs[a-1].name); scanf("%d",&d); while(d<=0||d>=INF){ printf("您输入的距离有误!请重新输入:\n"); scanf("%d",&d); } M.edges[a-1][M.v]=M.edges[M.v][a-1]=d; } strcpy(M.vexs[M.v].name,newName); strcpy(M.vexs[M.v].xinxi,newxinxi); M.v++; M.e=M.e+m; printf("地点添加成功!\n"); system("pause"); }/*先通过当前节点数的数值来判断是否可以添加地点,可以的话通过字符串复制语句(strcpy)来写入新的地点信息,再通过输入相邻的节点数来将数据准确存储在对应的一维数组位置上*/ ```  ### 删除现有地点子函数 ``` void Deletejd(){ system("cls"); int a,i,j,c=0; if(M.v<1){ printf("导航图中无地点,无法删除!\n"); system("pause"); return ; } showjd(); printf("请输入您要删除的地点编号:\n"); scanf("%d",&a); while(a<1||a>M.v){ printf("您的输入有误,请重新输入!范围在1~%d之间。\n",M.v); scanf("%d",&a); } printf("地点:【%s】正在删除...\n",M.vexs[a-1].name); for(i=0; i<M.v; i++){ if(M.edges[a-1][i]!=INF) c++; } for(i=a-1; i<M.v; i++){ M.vexs[i]=M.vexs[i+1]; } for(i=0; i<M.v; i++){ for(j=a-1; j<M.v; j++) M.edges[i][j]=M.edges[i][j+1]; } for(i=0; i<M.v; i++){ for(j=a-1; j<M.v; j++) M.edges[j][i]=M.edges[j+1][i]; } M.v--; M.e=M.e-c; printf("地点删除成功!\n"); system("pause"); }/*先通过当前节点数的数值来判断是否可以删除地点,可以删除时,通过分别对无向图的2条无向边进行更改来实现*/ ```  ### 增加新的道路子函数 ``` void Increaselj(){ system("cls"); int a,b,d; if(M.v<=1){ if(M.v==1){ printf("导航图中只有一个地点,无法添加道路!\n"); system("pause"); return ; }else{ printf("导航图中无地点,无法添加道路!\n"); system("pause"); return ; } } showjd(); printf("当前导航图中含有%d条道路!\n",M.e); printf("请输入您要添加道路的两个地点代号,中间使用空格隔开:\n"); scanf("%d %d",&a,&b); while(a<1||a>M.v||b<1||b>M.v||a==b){ if(a==b) printf("您输入的地点代号相同,请重新输入!\n"); else printf("您的输入有误,请重新输入!范围在1~%d之间。\n",M.v); scanf("%d %d",&a,&b); } if(M.edges[a-1][b-1]!=INF) printf("【%s】与【%s】之间已经存在一条道路,无需再次添加!\n",M.vexs[a-1].name,M.vexs[b-1].name); else{ printf("请输入【%s】和【%s】之间道路的长度:\n",M.vexs[a-1].name,M.vexs[b-1].name); scanf("%d",&d); while(d<=0||d>=INF){ printf("您输入的长度有误,请重新输入!\n"); scanf("%d",&d); } M.edges[a-1][b-1]=M.edges[b-1][a-1]=d; M.e++; printf("道路添加成功!当前导航图中含有%d条道路!\n",M.e); } system("pause"); }/*先通过当前节点数的数值来判断是否可以添加道路,并对输入的地点代号也进行区间判断,符合条件时写入二维数组边的长度*/ ```  ### 删除现有道路子函数 ``` void Deletelj(){ int a,b; system("cls"); if(M.v<=0){ printf("导航图中无地点,无法删除!\n"); system("pause"); return ; } if(M.e<=0){ printf("导航图中无道路,无法删除!\n"); system("pause"); return ; } showjd(); printf("当前导航图中一共有%d条道路\n",M.e); printf("请输入您要删除的道路对应的两个地点代号,中间使用空格隔开:\n"); scanf("%d %d",&a,&b); while(a<1||a>M.v||b<1||b>M.v||a==b){ if(a==b) printf("您输入的地点代号相同,请重新输入!\n"); else printf("您的输入有误,请重新输入!范围在1~%d之间,地点代号不同。\n",M.v); scanf("%d %d",&a,&b); } if(M.edges[a-1][b-1]>=INF) printf("%s与%s之间没有道路,无法删除!\n",M.vexs[a-1].name,M.vexs[b-1].name); else{ printf("正在删除【%s】与【%s】之间的道路...\n",M.vexs[a-1].name,M.vexs[b-1].name); M.edges[a-1][b-1]=M.edges[b-1][a-1]=INF; M.e--; printf("道路删除成功!当前导航图中含有%d条道路!\n",M.e); } system("pause"); }/*先通过当前节点数的数值和边数的数值来判断是否可以删除道路,当可以时将边的长度设为INF的值(假定为无穷路径)即代表道路删除成功*/ ```  ### 查找当前地点到其它地点的最短路径子函数(***) ``` void Zdlj(){ system("cls"); int a,i,j,k,min,pre; int b[JD],minl[JD],shanl[JD];/*存放原来的节点和已生成的终点、存放最短路径的长度、存放上一条路的位置*/ if(M.v<=1){ if(M.v==1){ printf("导航图中只有一个地点,无法查询最短路径!\n"); system("pause"); return ; }else{ printf("导航图中无地点,无法查询最短路径!\n"); system("pause"); return ; } } if(M.e<=0){ printf("导航图中无道路,无法查询最短路径!\n"); system("pause"); return ; } showjd(); printf("请输入您所在地点位置的代号:\n"); scanf("%d",&a); while(a<1||a>M.v){ printf("您的输入有误,请重新输入!范围在1~%d之间。\n",M.v); scanf("%d",&a); } b[a-1]=1; for(i=0; i<M.v; i++){ minl[i]=M.edges[a-1][i]; shanl[i]=a-1; b[i]=0; } minl[a-1]=0; b[a-1]=1; shanl[a-1]=-1; for(i=0; i<M.v; i++){ min=INF+1; for(k=1; k<M.v; k++){ if(b[k]==0&&minl[k]<min){ j=k; min=minl[k]; } } b[j]=1; for(k=0; k<M.v; k++){ if(b[k]==0&&(minl[j]+M.edges[j][k]<minl[k])){ minl[k]=minl[j]+M.edges[j][k]; shanl[k]=j; } } } int flag=1; for(i=0; i<M.v; i++){ if(i!=a-1){ if(minl[i]!=INF){ flag=0; printf("%d米: %s",minl[i],M.vexs[i].name); pre=shanl[i]; while(pre>=0){ printf(" <---> %s",M.vexs[pre].name); pre=shanl[pre]; } printf("\n"); } } } if(flag!=0) printf("【%s】与任何地点之间都没有可通道路!\n",M.vexs[a-1].name); system("pause"); }/*用Dijkstra算法求无向网M中定点到其余定点的最短路径及其带权长度*/ ```  ### 查找任一的两个地点之间的最短路径子函数 ``` void Zdlj_2(){ system("cls"); int a,b,i,j,k,min,pre,s[JD],minl[JD],shanl[JD];/*存放原来的节点和已生成的终点、存放最短路径的长度、存放上一条路的位置*/ if(M.v<=1){ if(M.v==1){ printf("导航图中只有一个地点,无法查询最短路径!\n"); system("pause"); return ; }else{ printf("导航图中无地点,无法查询最短路径!\n"); system("pause"); return ; } } if(M.e<=0){ printf("导航图中无道路,无法查询最短路径!\n"); system("pause"); return ; } showjd(); printf("请输入您要查询距离的两个地点代号,中间用空格隔开:\n"); scanf("%d %d",&a,&b); while(a<1||a>M.v||b<1||b>M.v){ printf("您的输入有误,请重新输入!范围在1~%d之间。\n",M.v); scanf("%d %d",&a,&b); } s[a-1]=1; for(i=0; i<M.v; i++){ minl[i]=M.edges[a-1][i]; shanl[i]=a-1; s[i]=0; } minl[a-1]=0; s[a-1]=1; shanl[a-1]=-1; for(i=0; i<M.v; i++){ min=INF+1; for(k=1; k<M.v; k++){ if(s[k]==0&&minl[k]<min){ j=k; min=minl[k]; } } s[j]=1; for(k=0; k<M.v; k++){ if(s[k]==0&&(minl[j]+M.edges[j][k]<minl[k])){ minl[k]=minl[j]+M.edges[j][k]; shanl[k]=j; } } } if(minl[b-1]==INF) printf("【%s】与【%s】地点之间没有可通道路!\n",M.vexs[a-1].name,M.vexs[b-1].name); else { printf("【%s】 <---> 【%s】之间的最短距离是%d米。 \n",M.vexs[b-1].name,M.vexs[a-1].name,minl[b-1]); pre=shanl[b-1]; printf("路径为:%s",M.vexs[b-1].name); while(pre>=0){ printf(" <---> %s",M.vexs[pre].name); pre=shanl[pre]; } } printf("\n"); system("pause"); }/*用Dijkstra算法求无向网M中定点到另一定点的最短路径及其带权长度*/ ```  --- ## 我自己创建的导航图以及验算表 <div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div><div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div> --- * 课程设计说明书: <div class="hideContent">此处内容需要评论回复后(审核通过)方可阅读。</div> 最后修改:2021 年 08 月 16 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏,谢谢
2 条评论
测试
写得好好哟,我要给你点赞!::funny:04::