实验题目:
Hanoi 塔问题
一、问题描述: 假设有三个分别命名为 A , B 和C 的塔座,在塔座 B 上插有n 个直径大小各不相同、从小到 大编号为1, 2,…,n 的圆盘。
现要求将塔座 B 上的n 个圆盘移至塔座 A 上并仍按同样顺序 叠排,圆盘移动时必须遵守以下规则:
(1 )每次只能移动一个圆盘;
(2)圆盘可以插在 A , B 和C 中任一塔上;
( 3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
要求: 用程序模拟上述问题解决办法,并输出移动的总次数,
圆盘的个数从键盘输入; 并想
办法计算出程序运行的时间。
二、 算法思路:
1 、建立数学模型: 这个问题可用递归法解决,并用数学归纳法又个别得出普遍解法:
假设塔座B 上有3个圆盘移动到塔座 A 上:
(1) "将塔座B 上2个圆盘借助塔座 A 移动到塔座C 上;
(2) "将塔座B 上1个圆盘移动到塔座 A 上;
(3) "将塔座C 上2个圆盘借助塔座 B 移动到塔座A 上。
其中第 2步可以直接实现。
第 1步又可用递归方法分解为:
1.1"将塔座B 上1个圆盘从塔座
1.2"将塔座B 上1个圆盘从塔座
1.3"将塔座A 上1个圆盘从塔座 第 3 步可以分解为:
3.1将塔座C 上1个圆盘从塔座
3.2将塔座C 上1个圆盘从塔座
3.3将塔座B 上1个圆盘从塔座 综上所述:可得到移动 3 个圆盘的步骤为
B->A,B->C, A->C, B->A, C->B, C->A, B->A,
2、算法设计:
将n 个圆盘由B 依次移到A , C 作为辅助塔座。
当 n=1时,可以直接完成。
否则,将塔 座B 顶上的n-1个圆盘借助塔座 A 移动到塔座C 上;然后将圆盘B 上第n 个圆盘移到塔 座A 上;最后将塔座 C 上的n-1个圆盘移到塔座 A 上,并用塔座B 作为辅助塔座。
三、原程序
#include<stdio.h> #include <iostream.h>
#include <windows.h> int times = 0;
void move(char a, char b)
{
printf("%c > %c \n", a,b);
}
void hno(int n,char a , char b, char c) {
if (n==1)
{
move(a,c);
times ++;
}
X 移动到塔座 A ; X 移动到塔座 C ; Z 移动到塔座 C 。
Y 移动到塔座 Y 移动到塔座 X 移动到塔座 B ; A
;
else
{
hn o( n-1,a,c,b);
move(a,c);
times ++;
hn o( n-1,b,a,c);
}
}
void mai n()
{
un sig ned start,fi ni sh;
int N;
printf("请输入汉诺塔的层数:");
scan f("%d",&N);
start=GetTickCou nt();〃
hn o(N,'B',C,'A');
fini sh=GetTickCou nt();
float time=(fi ni sh-start)/1000.0;
printf("共移动了%d 次! \n",times);
cout<<"总共需要时间为:"<<time<<endl;
}
四:
-C:MJ5er5\5t>ny\Deslrtop\hornework,,..^3L i]nI31\D#bug\Cppl ewe*
五.结论分析通过对上述递归在Hanoi 塔问题上的应用分析,可以得出如下结论:递归应用中的Hanoi 塔问题分析递归应用中的
1、Hanoi 塔问题中函数调用时系统所做工作一个函数在运行期调用另一个函数时,在运行被调
用函数之前,系统先完成 3 件事:
①将所有的实参、返回地址等信息传递给被调用函数保存。
②为被调用函数的局部变量分配存储区;
◎将控制转移到被调用函数的入口。
从被调用函数返回调用函数前,系统也应完成 3 件事:
①保存被调用函数的结果;
②释放被调用函数的数据区;
③依照被调用函数保存的返回地址将控制转移到调用函数。
当有多个函数构成嵌套调
用时,按照“后调用先返回”的原则,上述函数之间的信息传递和控制转移必须通
过“栈”来实现,即系统将整个程序运行时所需的数据空间安排在一个栈中,每当调
用一个函数时,就为其在栈顶分配一个存储区,每当从一个函数退出时,就释放其存
储区,因此当前运行函数的数据区必在栈顶。
2、递归调用过程中,在程序执行之前无法知道控制这种调用栈的规模,因为这一规模取决于递归调用的次序。
在这种情况下,程序的地址空间可能动态变化;
3、递归应用于程序设计时,结构清晰、程序易读,编制和调试程序很方便,不需要用户自行管理递归工作栈。
但递归应用于计算机时需要占用大量系统资源(包括堆栈、软中断和存贮空间等),并消耗大量处理时间。
因此,可以考虑采用并行计算进行处理,但
4、递归是串行的,其第n 步运算依赖于第n-1 步运算,所以在计算机软件理论上不存在递归问题并行计算的可能性。
实际上是否存在并行递归计算有待进一步探讨。