递归的基本概念
递归是一种对重复结构的描述, 程序中表现为程序自己调用本身.其本质是把问题拆分为一类更小的子问题,当问题粒度足够小的时候我们就把结果直接返回,然后继续去把问题拆分为与原有问题结构相同的更小问题,解决每个这样的小问题,最后将这些问题的解进行合并返回
递归的执行过程
- 如果问题足够小直接返回结果
- 拆分问题成与原问题结构相同的更小问题
- 解决每个这样的小问题
- 将这些小问题的解合并
- 返回合并最终结果
求阶乘算法
问题:求数字n的阶乘
function factorial(n){
// 1.当问题足够小直接返回结果
if(n==0){
return 1
}else{
// 2.把问题拆解为与原问题相同的更小子问题
return n*factorial(n-1)
}
}
汉诺塔问题
汉诺塔问题规则就不细说了,我们直接运用递归的思想来分析问题
假设有A B C三根柱子
-
当问题足够小只有一个盘子, 直接moveDisk A => C
-
有两个盘子我们先把第一个个盘子moveDisk A => B ,然后把剩下的盘子moveDisk A => C, 然后moveDisk B => C
-
有三个盘子我们先把前两个盘子移动到B上,moveDisk A => C,moveDisk A => B,moveDisk C => B,然后把剩下的盘子移动到CmoveDisk A => C,最后把B上的俩盘子通过A移动到C,moveDisk B => A ,moveDisk B => C,moveDisk A => C
-
....
-
有n个盘子的时候我们就将问题拆分n-1个盘子移动到B然后,最大的移动到C,然后把B上的盘子问题再拆分为n-1个盘子通过空柱子移动到C
汉诺塔问题重点在于理解,它总是通过一个空柱子把最大的移动到目标位置,有点蒙不要紧来看代码
function moveDisk(from, use, to){
console.log('把'+from+'移动到'+to)
}
function hanoi(n, A, B, C){
if(n==1){
moveDisk(A, B, C)
}else{
hanoi(n-1, A, C, B)
moveDisk(A, B, C)
hanoi(n-1, B, A, C)
}
}
hanoi(3, 'A', 'B', 'C')
//把A移动到C
//把A移动到B
//把C移动到B
//把A移动到C
//把B移动到A
//把B移动到C
//把A移动到C