使用递归方式解决汉诺塔问题,具体思路就不详细叙述了,代码如下:
#include <iostream>
using namespace std;
int i;
void moveDisk(int diskNum, char from, char to, char aux)
{
if(diskNum == 1){
cout << "step" << ++i << ": ";
cout << "Move disk1 from " << from
<< " to " << to << "\n";
}
else{
moveDisk(diskNum - 1, from, aux, to);
cout << "step" << ++i << ": ";
cout << "Move disk" << diskNum
<< " from " << from << " to " << to << "\n";
moveDisk(diskNum - 1, aux, to, from);
}
}
int main()
{
int init;
cin >> init;
moveDisk(init, 'A', 'C', 'B');
return 0;
}
自己在运行时,发现了这样的问题,当输入层数init大于等于10时,命令行输出中没有大于等于10的盘号!一开始以为是实现思路有问题,但反复思考几遍并没有发现问题,然后我认为可能编译器对嵌套层数有要求,当层数太大时,超过了规定嵌套层数而导致输出错误,按照这一思路查找相关信息,发现应该不是这个原因,编译器对嵌套层数一般没有要求,可能出现错误的情况是嵌套层数太深导致堆栈溢出,而10层的汉诺塔求解是不可能让堆栈溢出的。
后来通过给每行输出加上步骤号(本来没有步骤号),发现原来命令行保存的行数是有限制的,大于10的盘号被顶上去了未能显示出来。。。
最后分析一下使用递归的方法解决汉诺塔问题的时间复杂度:
令盘数为n,执行次数为f(n),
当n=1时,f(1)=1;
当n=2时,f(2)=2*f(1)+1=3;
当n=3时,f(3)=2*f(2)+1=7;
.........
当n=n时,f(n)=2*f(n-1)+1;
由上面的公式变形可得f(n)+1=2[f(n-1)+1],则f(n)+1=2^2*[f(n-2)+1]=...=2^(n-1)*[f(1)+1]=2^n,
则f(n)=2^n-1,按照O阶的写法,复杂度为O(2^n)。