当前位置:文档之家› 07141326汉诺塔-课程设计

07141326汉诺塔-课程设计

汉诺塔课程设计
报告
目录
一、需求分析 (3)
二、概要设计 (4)
三、详细设计 (6)
四、测试与分析 (7)
五、总结 (7)
六、附录:源程序清单 (8)
一、需求分析
1.1问题描述
汉诺塔(又称河内塔)问题是印度的一个古老的传说。

开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。

这是一个著名的问题,几乎所有的教材上都有这个问题。

由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以64个盘的移动次数是:
18,446,744,073,709,551,615
这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。

我们仅能找出问题的解决方法并解决较小N值时的汉诺塔,但很难用计算机解决64层的汉诺塔。

后来,这个传说就演变为汉诺塔游戏:
1.有三根杆子A,B,C。

A杆上有若干圆盘
2.每次移动一块圆盘,小的只能叠在大的上面
3.把所有圆盘从A杆全部移到C杆上
经过研究发现,汉诺塔的破解很简单,就是按照移动规则向一个方向移动圆盘:如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C
此外,汉诺塔问题也是程序设计中的经典递归问题。

将n个盘子从a座移动到c座可以分解为以下3个步骤:
(1)将a上n-1个盘借助c座先移到b座上。

(2)把a座剩下的一个盘移到c座上。

(3)将n-1个盘从c座借助于a座移到c座上。

1.2基本要求
(1)输入的形式和输入值的范围:
输入圆盘的数量,类型为整型,大于零。

(2)输出的形式:
运行结果为用字母表示移动盘子的方案,而并非是真正移动盘子。

(3) 程序所能达到的功能;
输入圆盘数量为定值时的移盘方案。

帮助我们更清晰的理解汉诺塔问题,及递归调用的应用。

二、概要设计
分析问题,找出移动圆盘的正确算法。

将n个盘子从a座移动到c座可以分解为以下3个步骤:
(1)将a上n-1个盘借助c座先移到b座上。

(2)把a座剩下的一个盘移到c座上。

(3)将n-1个盘从c座借助于a座移到c座上。

为了更清楚地描述算法,可以定义一个函数movedisc(n,a,b,c)。

该函数的功能是:将N个圆盘从A杆上借助C杆移动到B杆上。

这样移动N个圆盘的工作就可以按照以下过程进行:
1) hanoi(n-1,a,c,b);
2) 将一个圆盘从a移动到b上;
3) hanoi(n-1,c,b,a);
重复以上过程,直到将全部的圆盘移动到位时为止。

三、详细设计
子函数://这个函数的做用是以辅助位置为辅助,把n个盘从起始移向目的移动盘(盘的个数n,起始,辅助,目的)
{
如果(n大于0)
{
移动盘(n-1,起始, 目的,辅助);
输出 Move disc 盘编号 from pile 起始值 to pile 目的值;
移动盘(n-1,辅助, 起始,目的); }
否则结束;
}
主函数:
{
定义盘数n;
输出“Please enter the number of disks to be moved:”;
输入圆盘数目;
调用子函数;
}
四、测试与分析
Please enter the number of disks to be moved:3
Move disc 1 from pile A to pile B
Move disc 2 from pile A to pile C
Move disc 1 from pile B to pile C
Move disc 3 from pile A to pile B
Move disc 1 from pile C to pile A
Move disc 2 from pile C to pile B
Move disc 1 from pile A to pile B
Please enter the number of disks to be moved:4
Move disc 1 from pile A to pile C
Move disc 2 from pile A to pile B
Move disc 1 from pile C to pile B
Move disc 3 from pile A to pile C
Move disc 1 from pile B to pile A
Move disc 2 from pile B to pile C
Move disc 1 from pile A to pile C
Move disc 4 from pile A to pile B
Move disc 1 from pile C to pile B
Move disc 2 from pile C to pile A
Move disc 1 from pile B to pile A
Move disc 3 from pile C to pile B
Move disc 1 from pile A to pile C
Move disc 2 from pile A to pile B
Move disc 1 from pile C to pile B
五、总结
数据结构,目的就是要锻炼我们的抽象思维,我们可以根据以前学习的C
语言的基础,更灵活的运用其进行编程。

但我发现,就目前的这点只是储备,就现在的实践能力,真的很难实现太多复杂的程序,思前想后,我最总决定来做这个需要抽象思维多但程序相对好实现的汉诺他问题。

用以来巩固对知识的理解。

“数据结构”定义了诸多抽象数据类型。

如:栈、队列,串等。

这些存储结构在分析问题解决问题时发挥了重要的作用。

就我选的这一题目而言。

在分析问题时栈起了关键性的作用。

汉诺塔问题是典型的递归问题。

语句看似简单,但是如果不借助栈来分析问题,实属不易。

经过了几天的努力,数据结构课程设计这项任务终于完成。

在这几天里,克服了重重困难,从一头雾水到渐渐思路变得相对清晰明了。

我们可以从最简单的汉诺他问题中去分析其规律,对每一层移动都是相同的方式,所以站的递归显得尤为重要。

虽然都说“程序=数据结构+算法”,但我在学习运用数据结构编程之前,并没能深刻体会到这一点,直到这次课程设计实践。

我感受最深的一点是:以前用C编程,只是注重如何编写函数能够完成所需要的功能,似乎没有明确的战术,只是凭单纯的意识和简单的语句来堆砌出一段程序。

感觉有点像张飞打仗,有勇无谋,只要能完成任务就行。

但现在编程感觉完全不同了。

在编写一个程序之前,自己能够综合考虑各种因素,首先选取自己需要的数据结构,是树还是图或是别的什么汉诺塔之类?然后选定一种或几种存
储结构来具体的决定后面的函数的主要风格。

最后在编写每一个函数之前,可以仔细斟酌比对,挑选出最适合当前状况的算法。

这样,即使在完整的程序还没有写出来之前,自己心中已经有了明确的原图了。

这样无形中就提高了自己编写的程序的质量。

另外,我还体会到深刻理解数据结构的重要性。

只有真正理解这样定义数据类型的好处,才能用好这样一种数据结构。

了解典型数据结构的性质是非常有用的,它往往是编写程序的关键。

总之,我会继续我的兴趣编写程序的,相信在越来越多的尝试之后,自己会不断进步不断提高的。

六、源程序清单
汉诺塔问题:有三个柱子,编号A、B、C,在A柱上有n个圆盘,直径不同,按直径从大到小依次叠放在柱子上,要求:把A柱上的圆盘借助B柱移动到C 柱。

每次移动一个,任何情况下保证大的在下,小的在上。

设计并实现该算法,输出搬动圆盘过程。

*/
#include"stdio.h"
void hanoi(int n,char a,char b,char c)
{if(n>0)
{ hanoi(n-1,a,c,b);
printf("\n Move disc %d from pile %c to pile %c",n,a,c);
hanoi(n-1,b,a,c); }}
void main()
{int n;
printf("Please enter the number of disks to be moved:");
scanf("%d",&n);
hanoi(n,'A','B','C');
}
参考文献
[1]徐建民,《语言程序设计》,电子工业出版社,2002年
[2]谭浩强,张基温,唐永炎,《C语言程序设计教程》,高等教育出版社
[3]谭浩强,《C程序设计》,清华大学出版社,2005年7月第3版
[4]谭浩强,《C程序设计题解与上机指导》,清华大学出版社,2005年7月第3版。

相关主题