数据结构课程设计汉诺塔问题.docx
- 文档编号:9012341
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:22
- 大小:60.34KB
数据结构课程设计汉诺塔问题.docx
《数据结构课程设计汉诺塔问题.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计汉诺塔问题.docx(22页珍藏版)》请在冰豆网上搜索。
数据结构课程设计汉诺塔问题
1.系统需求分析
1.1问题描述
(一)、课程设计题目:
汉诺塔问题
(二)、目的与要求:
1、目的:
(1)要求学生达到进一步熟练掌握C语言的基本知识和技能;
(2)基本掌握利用VC++6.0制作页面的基本思路和方法;
(3)能够利用所学的基本知识和技能,解决简单的汉诺塔问题。
2、基本要求:
(1)要求利用VC++6.0以及MFC控件来完成系统的设计;
(2)要求在设计的过程中,建立清晰的类层次;
(3)在系统中定义类,每个类中要有各自的属性和方法;
(4)在系统的设计中,至少要用到C中的一种算法。
3、创新要求:
在基本要求达到后,可进行创新设计,如根据查找结果进行修改的功能。
4、写出设计说明书
(三)、设计方法和基本原理:
1、问题描述(功能要求):
界面划出大小不等,颜色不同的矩形块分别代表各盘子,盘子规模n为1~10,并可以选择人工控制演示和系统自动运行演示,如果是自动则还要输入演示速度。
在界面的上方显示正在移动的盘子的源座和目标座。
用人工操作时,按任意键移动一个盘子,这样可以清楚每一步过程。
如果是自动运行,可以选择移动一步的暂停时间。
要求用TurboC或VC6.0MFC实现的汉诺塔问题的图形程序。
设计思路:
用栈存放塔,定义三个堆栈,用来表示三个塔座,栈的每个结点类型为结构体,其中数据域存放盘子的代号,根据代号计算盘子的大小。
Top为塔的栈顶指针,即每个塔的具体高度。
例如,结构体可以定义如下:
StructH
{intdata[15];/*存放每个盘的代号*/
inttop;/*每个塔的具体高度*/
}num[3];
2、问题的解决方案:
根据系统功能要求,可以将问题解决分为以下步骤:
(1)利用VC++中的MFC控件制作出汉诺塔运行页面;
(2)完成类中各个成员函数的定义;
(3)完成系统的应用模块,根据不同按键的功能,在源程序中填入相应的代码;
(4)功能调试;
(5)完成系统总结报告以及系统使用说明书。
2.概要设计
2.1设计思路
对于一个类似的这样的问题,任何一个人都不可能直接写出移动盘子的每一个具体步骤。
可以利用这样的统筹管理的办法求解:
我们假设把该任务交给一个僧人,为了方便叙述,将他编号为64。
僧人自然会这样想:
假如有另外一个僧人能有办法将63个盘子从一个座移到另一个座,那么问题就解决了,此时僧人64只需这样做:
1.命令僧人63将63个盘子从A座移到C座
2.自己将最底下的最大的一个盘子从A座移到C座
3.再命令僧人63将63个盘子从B座移到C座
为了解决将63个盘子从A座移到B座的问题,僧人63又想:
如果能再有一个僧人62能将62个盘子移动到另一座,我就能将63个盘子从A座移动到B座。
他是这样做的:
1.命令僧人62将62个盘子从A移动到C
2.自己将一个盘子从A座移动到B座
3.再命令僧人62将62个盘子移到B座
再进行一次递归。
如此“层层下放”,直到后来找到第2个僧人,让他完成将2个盘子从一个座移到另一个座,进行到此,问题就解决了。
最后找到第1个僧人,让他完成将一个盘子从一个座移动到另一个座,至此,全部工作已经完成,都是可以执行的。
按照如此的思路设计递归算法,很容易得出盘子的移动方案。
另外是图形演示盘子的移动过程。
为了能够更加形象的表示盘子的移动过程。
在设计图形演示的时候,我们采用了图形动态演示。
首先我们将字幕、柱子、以及提示信息等等屏幕内容设置成固定不变,我们这里称之为舞台。
我们将盘子看作对象,一个盘子一个对象。
在设计演示过程的时候,只需要将盘子对象放置于二维界面中的不同信置,通过刷新屏幕,实现动画显示。
2.2系统总体设计
先对程序进行各功能类的定义,定义汉诺塔,显示塔的定义,运行盘子移动的函数,一般可以使用移动、显示等功能,运用数据结构的相关知识,利用一定的算法制作出汉诺塔程序。
能输入塔盘的数量(10以内)和塔盘移动速度,支持人和电脑操作,并且显示移动过程和移动次数,实现汉诺塔的动态掩饰,总的设计思路如下图所示:
该出租车计费系统由四个模块组成,分别是:
塔盘数量设置:
在1到10之间
移动速度调节:
以1000为一秒,输入移动速度
操作对象选择:
有人和电脑连个对象选择
移动过程显示:
将盘子移动的过程显示出来
各模块之间的关系为:
图1.汉诺塔功能结构体图
2.3程序流程图
2.3.1塔盘数量设置
图2.1塔盘数量设置部分
2.3.2移动速度调节
图2.2移动速度调节部分
2.3.3操作对象选择
图2.3操作对象选择部分
2.3.4汉诺塔求解流程图
游戏开始
输入塔盘数量n
0 调用while()进入主函数 是否为人 输入移动速度 移动塔盘 是否小盘在大盘之上 塔盘全部在C座 输出移动次数 游戏结束 图2.4汉诺塔求解流程图 3.详细设计 3.1模块设计 3.1.1塔和塔显示的定义 structT { inth;//塔的高度 intx;//塔的第一个盘的x坐标,y坐标等于(7+n-塔的高度h) intl;//塔的第一个盘的长度 }ta[3]={{10,15,2},{0,0,0},{0,0,0}}; charhnt[18][79]={ {""}, {""}, {""}, {"╔════════════════════════════════════╗"}, {"║║"}, {"║║"}, {"║║"}, {"║▆║"}, {"║▆▆║"}, {"║▆▆▆║"}, {"║▆▆▆▆║"}, {"║▆▆▆▆▆║"}, {"║▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆▆▆║"}, {"╚════════════════════════════════════╝"}}; intn; intsum=0; intcomputerorpeople=1; intspeed=0; voidcount_ta_1(intta_1) { inti; intj; intk=0; for(i=7;i<7+n;i++) for(j=4+ta_1*24;j<28+ta_1*24;j++) { if(hnt[i][j]! ='') { for(;hnt[i][j+k]! ='';k++); ta[ta_1].x=j; ta[ta_1].l=k; return; } } } 3.1.2塔盘移动的定义 voidmove(intta_1,intta_3) { inti; sum++; ta[ta_3].h++; ta[ta_3].x=ta[ta_1].x+(ta_3-ta_1)*24; ta[ta_3].l=ta[ta_1].l; for(i=0;i { hnt[7+n-ta[ta_3].h][ta[ta_3].x+i]=hnt[7+n-ta[ta_1].h][ta[ta_1].x+i]; hnt[7+n-ta[ta_1].h][ta[ta_1].x+i]=''; } ta[ta_1].h--; count_ta_1(ta_1); system("cls"); //system("clear"); for(i=0;i<7+n;i++) printf("%s\n",hnt[i]); printf("%s",hnt[17]); printf("\n\n从%c塔移动一个盘到%c塔\n",ta_1+65,ta_3+65); printf("\n步数: %d\n\n",sum); if(computerorpeople==2) system("pause"); else for(i=0;i<200000*speed;i++); } 3.1.3塔盘移动规律的定义 voidhanoi(intta_1,intta_2,intta_3,intm)//递归,ta_1/ta_2/ta_3分别为3座塔的代号,m为盘子数 { if(m==1) move(ta_1,ta_3);//如果盘子为1,将这个盘子从塔座A移动到塔座C else { hanoi(ta_1,ta_3,ta_2,m-1);//将塔座A的前m-1个盘子移到塔座B move(ta_1,ta_3);//将塔座A的第m个盘子移到塔座C hanoi(ta_2,ta_1,ta_3,m-1);//将塔座B的m-1个盘子移到塔座C } } 3.1.4主函数main() voidmain() { inti; printf("请输入汉诺塔的高度(范围1->10): "); scanf("%d",&n); printf("请选择: 输入1由电脑自动控制;\n"); printf("输入2由人控制。 \n"); printf("请输入: "); scanf("%d",&computerorpeople); if(computerorpeople! =1&&computerorpeople! =2) computerorpeople=1; if(computerorpeople==1) { printf("请输入移动盘的速度(例如: 输入1000则代表1秒): "); scanf("%d",&speed); } if(n<1||n>10) n=10; ta[0].h=n; system("cls");//执行dos下的清屏命令 //system("clear"); for(i=0;i<7+n;i++) printf("%s\n",hnt[i]); printf("%s\n\n",hnt[17]); system("pause"); hanoi(0,1,2,n); if(computerorpeople==1) system("pause"); } 4.系统调试 (1)程序编写过程中对文件调用不熟悉,子函数调用不到位,根据题设条件不断改进才逐步完善。 (2)结构语句编写错误,不能准确把握在哪里终止,但通过书上的例题可以掌握。 (3)程序编写时容易出现一些小错误,比如没有分号、缺了大括号等等,需要编写完后仔细检查。 (4)程序运行虽然没有错误,不能达到想要的效果,这时就需要借鉴大家的意见,共同商讨最佳的答案。 5.运行结果 (1)有电脑自动控制的时候: 图5.1主菜单 (2)汉诺塔游戏界面: 图5.2汉诺塔界面 图5.3汉诺塔塔盘移动界面 (3)有人控制的时候: 图5.4塔盘移动有人控制选择菜单 图5.4汉诺塔塔盘移动有人控制界面1 图5.4汉诺塔塔盘移动有人控制界面2 图5.4汉诺塔塔盘移动有人控制界面3 (4)塔盘搬到C盘的界面: 图5.5塔盘搬到C盘的界面 6.心得体会 通过此次课程设计,使我更加扎实的掌握了有关数据结构迷宫方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。 实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。 过而能改,善莫大焉。 在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。 最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。 这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。 在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可! 课程设计诚然是一门专业课,给我很多专业知识以及专业技能上的提升,同时又是一门讲道课,一门辩思课,给了我许多道,给了我很多思,给了我莫大的空间。 同时,设计让我感触很深。 使我对抽象的理论有了具体的认识。 通过这次课程设计,我进一步熟悉了VC++6.0软件的使用。 我认为,在这学期的实验中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。 更重要的是,在实验课上,我们学会了很多学习的方法。 而这是日后最实用的,真的是受益匪浅。 要面对社会的挑战,只有不断的学习、实践,再学习、再实践。 这对于我们的将来也有很大的帮助。 以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。 就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。 回顾起此课程设计,至今我仍感慨颇多,从理论到实践,在这段日子里,可以说得是苦多于甜,但是可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。 通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。 在设计的过程中遇到问题,可以说得是困难重重,但可喜的是最终都得到了解决。 实验过程中,也对团队精神的进行了考察,让我们在合作起来更加默契,在成功后一起体会喜悦的心情。 果然是团结就是力量,只有互相之间默契融洽的配合才能换来最终完美的结果。 此次设计也让我明白了思路即出路,有什么不懂不明白的地方要及时请教或上网查询,只要认真钻研,动脑思考,动手实践,就没有弄不懂的知识,收获颇丰。 7.附录 7.1参考书目 数据结构教程/李春葆等编著.——3版.——北京: 清华大学出版,2009.3 7.2源程序 #include #include #include #include #include structT { inth;//塔的高度 intx;//塔的第一个盘的x坐标,y坐标等于(7+n-塔的高度h) intl;//塔的第一个盘的长度 }ta[3]={{10,15,2},{0,0,0},{0,0,0}}; charhnt[18][79]={ {""}, {""}, {""}, {"╔════════════════════════════════════╗"}, {"║║"}, {"║║"}, {"║║"}, {"║▆║"}, {"║▆▆║"}, {"║▆▆▆║"}, {"║▆▆▆▆║"}, {"║▆▆▆▆▆║"}, {"║▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆▆║"}, {"║▆▆▆▆▆▆▆▆▆▆║"}, {"╚════════════════════════════════════╝"}}; intn; intsum=0; intcomputerorpeople=1; intspeed=0; voidcount_ta_1(intta_1) { inti; intj; intk=0; for(i=7;i<7+n;i++) for(j=4+ta_1*24;j<28+ta_1*24;j++) { if(hnt[i][j]! ='') { for(;hnt[i][j+k]! ='';k++); ta[ta_1].x=j; ta[ta_1].l=k; return; } } } voidmove(intta_1,intta_3) { inti; sum++; ta[ta_3].h++; ta[ta_3].x=ta[ta_1].x+(ta_3-ta_1)*24; ta[ta_3].l=ta[ta_1].l; for(i=0;i { hnt[7+n-ta[ta_3].h][ta[ta_3].x+i]=hnt[7+n-ta[ta_1].h][ta[ta_1].x+i]; hnt[7+n-ta[ta_1].h][ta[ta_1].x+i]=''; } ta[ta_1].h--; count_ta_1(ta_1); system("cls"); //system("clear"); for(i=0;i<7+n;i++) printf("%s\n",hnt[i]); printf("%s",hnt[17]); printf("\n\n从%c塔移动一个盘到%c塔\n",ta_1+65,ta_3+65); printf("\n步数: %d\n\n",sum); if(computerorpeople==2) system("pause"); else for(i=0;i<200000*speed;i++); } voidhanoi(intta_1,intta_2,intta_3,intm)//递归,ta_1/ta_2/ta_3分别为3座塔的代号,m为盘子数 { if(m==1) move(ta_1,ta_3);//如果盘子为1,将这个盘子从塔座A移动到塔座C else { hanoi(ta_1,ta_3,ta_2,m-1);//将塔座A的前m-1个盘子移到塔座B move(ta_1,ta_3);//将塔座A的第m个盘子移到塔座C hanoi(ta_2,ta_1,ta_3,m-1);//将塔座B的m-1个盘子移到塔座C } } voidmain() { inti; printf("请输入汉诺塔的高度(范围1->10): "); scanf("%d",&n); printf("请选择: 输入1由电脑自动控制;\n"); printf("输入2由人控制。 \n"); printf("请输入: "); scanf("%d",&computerorpeople); if(computerorpeople! =1&&computerorpeople! =2) computerorpeople=1; if(computerorpeople==1) { printf("请输入移动盘的速度(例如: 输入1000则代表1秒): "); scanf("%d",&speed); } if(n<1||n>10) n=10; ta[0].h=n; system("cls");//执行dos下的清屏命令 //system("clear"); for(i=0;i<7+n;i++) printf("%s\n",hnt[i]); printf("%s\n\n",hnt[17]); system("pause"); hanoi(0,1,2,n); if(computerorpeople==1) system("pause"); } 8评分表 计算机与通信学院课程设计评分表 课题名称: 数据结构 项目 评价 设计方案的合理性与创造性 设计与调试结果 设计说明书的质量 答辩陈述与回答问题情况 课程设计周表现情况 综合成绩 教师签名: 日期:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 汉诺塔 问题