题目
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
演化后:
从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数。
关于递归
这个题要用递归的方法,之前学过,但是半吊水,这次查阅了很多资料,也做了总结。
首先,什么是递归,就是最简单的理解就是自己调用自己,原因就是这个问题可以被分为许多个子问题,而每个子问题的解法是一样的,另外还用就是这个调用不是无止境的,需要一个终止条件,要有临界点,不然不会出结果,会无限制循环下去,无底洞。这里有一个例子非常形象的展示了递归的所有特点。那就是算阶乘
js:
var hao = function(n){
if(n==0){
return 1;
}else if(n>0){
return n*hao(n-1);
}
}
console.log (hao(3));
他的执行流程是这样的
每一次都执行着上一次的操作直到到达终止条件,汉诺塔问题相对复杂。但原理相似。先看一下汉诺塔的规律。
一个盘
操作:
1号盘A——>C
两个盘
操作:
1号盘A——>B
2号盘A——>C
1号盘B——>C
三个盘
操作:
1号盘A——>C
2号盘A——>B
1号盘C——>B
3号盘A——>C
1号盘B——>A
2号盘B——>C
1号盘A——>C
所以看似复杂,其实只要都是往c的方向走,真正的操作只有三种,A——>B,
A——>C,B——>C。(这里说的操作包括通过别的柱子到达目的地柱子的也算)
所以这个递归中的子问题就是这三个操作,然后找规律。
一个盘
A——>B 0次,A——>C 1次,B——>C 0次
两个盘
A——>B 1次,A——>C 2次,B——>C 1次
三个盘
A——>B 2次,A——>C 3次,B——>C 2次
所以操作次数与盘数n的关系是
A——>B (n-1)次,A——>C n次,B——>C (n-1)次
而他的临界就是n=1
代码实现
js:
function hanota(n,A,B,C){
if(n==1){//到达临界点n次A-C的操作
console.log("1号盘"+A+"--->"+C);
}else{
hanota(n-1,A,C,B)//进行n-次A-B的操作
console.log(n+"号盘"+A+"--->"+C);
hanota(n-1,B,A,C)//进行n-次B-C的操作
}
}
hanota(3,"a","b","c");
结果
总结
从前有座山,山里有座庙,庙里有个老和尚讲故事,讲什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲什么呢?。。。