汉诺塔

实验内容:

假设有三个分别命名为 A,B 和 C的塔座,在塔座 B 上插有 n 个直径大小各不相同、从小到 大编号为 1,2,…, n 的圆盘。现要求将塔座 B上的 n 个圆盘移至塔座 A 上并仍按同样顺序 叠排,圆盘移动时必须遵守以下规则: (1)每次只能移动一个圆盘; (2)圆盘可以插在 A,B 和 C中任一塔上; (3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。 要求: 用程序模拟上述问题解决办法,并输出移动的总次数, 圆盘的个数从键盘输入; 并想 办法计算出程序运行的时间。

实验步骤:

这个问题可用递归法解决,并用数学归纳法又个别得出普遍解法: 假设塔座 B 上有 3 个圆盘移动到塔座 A 上: ( 1)" 将塔座 B上 2 个圆盘借助塔座 A 移动到塔座 C上; ( 2)" 将塔座 B上 1 个圆盘移动到塔座 A 上; ( 3)" 将塔座 C上 2 个圆盘借助塔座 B 移动到塔座 A 上。 其中第 2 步可以直接实现。第 1 步又可用递归方法分解为: 1.1" 将塔座 B上 1 个圆盘从塔座 X移动到塔座 A; 1.2" 将塔座 B上 1 个圆盘从塔座 X移动到塔座 C; 1.3" 将塔座 A上 1 个圆盘从塔座 Z 移动到塔座 C。 第 3 步可以分解为: 3.1 将塔座 C上 1 个圆盘从塔座 Y移动到塔座 B; 3.2 将塔座 C上 1 个圆盘从塔座 Y移动到塔座 A; 3.3 将塔座 B上 1 个圆盘从塔座 X移动到塔座 A。 综上所述:可得到移动 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<iostream>
#include<cstdio>
using namespace std;
//将n个盘子从x借助y移动到z 
void move(int n, char x, char y, char z){
    if(n == 1){
        printf("%c --> %c\n",x,z);
    }
    else {
        move(n - 1, x, z, y);  //将n-1个盘子从x借助z移动到y上 
        printf("%c --> %c\n",x,z);  //将最底下的第n个盘子从x移动到z上 
        move(n - 1, y, x, z);  //将n-1个盘子从y借助x移动到z上 
    }
}
int main(){
    int n;
    cin >> n;
    move(n, 'X', 'Y', 'Z'); 
    return 0;
}
 

反思总结:

通过对上述递归在 Hanoi 塔问题上的应用分析,可以得出如下结论: 递归应用中的 Hanoi 塔问题分析递归应用中的 1、Hanoi 塔问题中函数调用时系统所做工作一个函数在运行期调用另一个函数时,在 运行被调用函数之前,系统先完成 3 件事: ○1 将所有的实参、返回地址等信息传递给被调用函数保存。 ○2 为被调用函数的局部变量分配存储区; ○3 将控制转移到被调用函数的入口。 从被调用函数返回调用函数前,系统也应完成 3 件事: ①保存被调用函数的结果; ②释放被调用函数的数据区; ③依照被调用函数保存的返回地址将控制转移到调用函数。当有多个函数构成 嵌套调用时,按照 “后调用先返回 ”的原则,上述函数之间的信息传递和控制转 移必须通过 “栈”来实现,即系统将整个程序运行时所需的数据空间安排在一个 栈中,每当调用一个函数时,就为其在栈顶分配一个存储区,每当从一个函数 退出时,就释放其存储区,因此当前运行函数的数据区必在栈顶。 2、递归调用过程中,在程序执行之前无法知道控制这种调用栈的规模,因为这一规模 取决于递归调用的次序。在这种情况下,程序的地址空间可能动态变化; 3、递归应用于程序设计时,结构清晰、程序易读,编制和调试程序很方便,不需要用 户自行管理递归工作栈。 但递归应用于计算机时需要占用大量系统资源 (包括堆栈、 软中断 和存贮空间等) ,并消耗大量处理时间。因此,可以考虑采用并行计算进行处理,但 4、递归是串行的,其第 n 步运算依赖于第 n-1 步运算,所以在计算机软件理论上不 存在递归问题并行计算的可能性。实际上是否存在并行递归计算有待进一步探讨。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值