目录
汉诺塔问题
1.有A、B、C三个柱子,每个柱子相邻。
2.A柱子从上到下按照从小到大的顺序叠放着n个圆盘
3.将A柱子上的圆盘移动到C柱子上,每次只能移动一个圆盘,且大圆盘不能在小圆盘上面。
注:这里将ABC三个圆盘分别分为起始盘,辅助盘,终点盘。
何为递归
递归简单来讲就是函数自己调用自己,且每次调用时函数中的参数都在不断变化,递归过程中需要给一个“出口”,否则函数会一直调用自己,直到程序崩溃,当函数找到“出口”时就会将该次递归的结果一层一层地回溯到递归的第一个函数,并得到最后结果。比如在斐波那契数列中:
public int fn(int n) {
if (n==1 || n==2){
return 1;
}
else {
return fn(n-1)+fn(n-2);
}
}
当n为5时,返回fn(4)+fn(3)
当n为4时,返回fn(3)+fn(2)
当n为3时,返回fn(2)+fn(1)
当n为2时,返回1
当n为1时,返回1
接下来将结果一层层回溯上去就得到了n为5时的斐波那契数列。
用递归来解决汉诺塔问题
上面已经说到,想要知道当前函数运行的结果需要得到下次递归得到的结果,所以在汉诺塔问题中,要移动n个圆盘就必须先移动n-1个圆盘,想要移动n-1个圆盘就必须移动n-2个圆盘......
例如现在有3个圆盘,想要将3个圆盘都移动到C柱子上就必须先移动上面2个圆盘,想移动上面两个圆盘就必须先移动最上面的圆盘,在移动时需要借助辅助柱,这里只演示2个圆盘。
先将第一个圆盘经过C柱(辅助柱)移动到B柱
再将A柱中的盘移动到C柱
最后将B柱子的盘经A柱移动到C柱
代码演示
package Data;
public class ljk {
public static void main(String[] args) {
Tower t = new Tower();
t.move(3,'A','B','C');
}
}
class Tower{
public void move(int n,char a,char b,char c){
if (n==1){//如果只剩下最后一个盘就直接移动到C柱
System.out.println(a+"->"+c);
}else {
move(n-1,a,c,b);//想要移动n个盘就先移动n-1个盘,这里的意思是将A柱上的盘经C柱移动到B柱
System.out.println(a+"->"+c);
move(n-1,b,a,c);//将B柱上的盘经A柱移动到C柱
}
}
}