先上代码:
#include <iostream>
using namespace std;
void han(int n, char Fr, char To, char Mid);
int step=1;
int main()
{
int n;
cin >> n;
han(n, 'A', 'B', 'C');
return 0;
}
void han(int n, char Fr, char Mid, char To)
{
if (n == 1)
cout<<step++<<":move from "<<Fr<<" to "<<To<<endl; /* Remark1 */
else
{
han(n-1,Fr,To,Mid);
cout<<step++<<":move from "<<Fr<<" to "<<To<<endl;
/* Remark2 */
han(n-1,Mid,Fr,To);
}
}
问题三步走:
1.将n-1个圆盘放置在b上;
2.将第n个圆盘放置在c上;
3.将n-1个圆盘放置在c上。
但如果仅仅以a、b、c去理解此处的形参,必然产生很多疑惑,所以这里我们引出三个名称:原始杆(Fr)、中介杆(Mid)和目的杆(To)。
于是我们的问题就可以被分为如下子问题:
将n个圆盘放置在目的杆;将n-1个圆盘放置在目的杆;将n-2个圆盘放置在目的杆.......
此时n-1的目的杆与n的目的杆不一样,同理n-2的目的杆也与n-1的目的杆不一样,所以我们可以发现abc杆的作用是在变化的。
以n为3为例:
整体三个以c为目的杆,则要上面两个圆盘到中介杆b,第三个圆盘到目的杆c;上面整体两个以b为目的杆,则以c为中介杆;剩最上面的一个,以c为目的杆,不需要借助中介杆了。
所以可总结为:
1.将n-1个圆盘放置在中介杆上;
2.将第n个圆盘放置在目的杆上;
3.将n-1个圆盘放置在目的杆上,回到1。
把握整体思路,即便实参,形参的位置改变也不会产生影响。
下列代码交换c,b位置:
#include <iostream>
using namespace std;
void han(int n, char Fr, char To, char Mid);
int step=1;
int main()
{
int n;
cin >> n;
han(n, 'A', 'C', 'B');
return 0;
}
void han(int n, char Fr, char To, char Mid)
{
if (n == 1)
cout<<step++<<":move from "<<Fr<<" to "<<To<<endl; /* Remark1 */
else
{
han(n-1,Fr,Mid,To);
cout<<step++<<":move from "<<Fr<<" to "<<To<<endl;
/* Remark2 */
han(n-1,Mid,To,Fr);
}
}
运行结果: