首先关于这个问题网上有两种代码,答案都相同
第一种
#include<iostream>
#include<string>
using namespace std;
int towers(int size,char f,char t,char s){ //这里f是startTower,t是spareTower,s是endTower
static int count=0;
if (size==1){
cout<<"move from "<<f<<" to "<<s<<endl;
count ++;
return count;
}
else{ // n不为1,分为下面一个圆盘和上面n-1个圆盘,先把上面n-1个移动到SpareTower
再把最下面一个移动到EndTower,最后把n-1个从SpareTower移动到EndTower
用递归就是这么简单!!
towers(size-1,f,s,t);
towers(1,f,t,s); //***
towers(size-1,t,f,s);
}
}
int main(){
cout<<"total num is "<<towers(3,'a','b','c')<<endl;
return 0;
}
要把n个圆盘从一个柱子(StartTower)搬到另一个柱子(EndTower)上,并满足题目的要求,需要借助空闲的柱子(SpareTower)。由于实现n个圆盘的搬移不太容易,可以换个角度思考,把n个圆盘分成1个和(n-1)个圆盘;这(n-1)个圆盘已经排好了顺序,利用3根柱子可以很容易地把这两组圆盘从一个柱子搬移到另一个柱子上。再把(n-1)个圆盘分成1个圆盘和(n-2)个。。。。。。每一个问题都与前一个问题类似,并且规模逐渐缩小,可以考虑采用递归的方法编写。
第二种
move(x, y) { printf(\t%c-->%c\n",x,y);
}
voidhannuota(intn, chara, charb, charc) //自定义hannuota函数,这里的a,b,c为形参,不代表具体哪根柱子
{
if(n == 1)
move(a, c); //调用自定义函数move
else
{
hannuota(n-1, a, c, b); //第一行递归
move(a, c); //调用自定义函数move//***
hannuota(n-1, b, a, c); //第二行递归
}
}
intmain(void)
{
intn;
printf("请输入要移动的块数:\n");
scanf("%d",& n);
hannuota(n, 'a', 'b', 'c');
return0;
}
/*执行详细步骤:当n = 3 时
n = 3 n = 2 n = 1
| |h(1, a, b, c)=>move(a, c)=> a->c //1
|h(2, a, c, b) |move(a, b) a->b //2
| |h(1, c, a, b)=>move(c, b)=> c->b //3
|
h(3, a, b, c) |move(a, c) a->c //4
|
| |h(1, b, c, a)=>move(b, a)=> b->a //5
|h(2, b, a, c) |move(b, c) b->c //6
| |h(1, a, b, c)=>move(a, c)=> a->c //7
|
执行结果:
请输入要移动的块数:
3
a-->c
a-->b
c-->b
a-->c
b-->a
b-->c
a-->c
*/
这就让我开始思考两代码中间被我打***符号的区别了,为什么他们的效果是一样的,由此开始思考递归的本质,