递归: 函数
例子4:上台阶 优化
上N级台阶,便可每次1步也可每次2步走,共有多少种不一样走法 spa
解法:迈出第一步有两种方法,第一步后就是N-1和N-2的走法了 递归
def step(n:Int):Int = if (n<=2) n else step(n-1)+step(n-2) ci
推广:若是每次可走1步或2步或3步,则 资源
def step(n:Int):Int = n match { case 1=>1; case 2=>2; case 3=>4; table
case _ =>step(n-1)+step(n-2)+step(n-3) } 循环
尾递归:
定义:函数尾(最后一条语句)是递归调用的函数。 方法
tail-recursive会被优化成循环,因此没有堆栈溢出的问题。 数据
线性递归的阶乘:
def nn1(n:Int):BigInt = if (n==0) 1 else nn1(n-1)*n
println(nn1(1000)) // 4023...000
println(nn1(10000)) // 崩溃:(
尾递归的阶乘:
def nn2(n:Int, rt:BigInt):BigInt = if (n==0) rt else nn2(n-1, rt*n)
println(nn2(1000,1)) // 40...8896
println(nn2(10000,1)) // 2846...000
def nn3(n:Int):BigInt = nn2(n,1)
对比:
线性递归 |
尾递归 |
nn1(5) |
nn2(5, 1) |
不算,直到递归到一个肯定的值后,又从这个具体值向后计算;更耗资源,每次重复的调用都使得调用链条不断加长. 系统使用栈进行数据保存和恢复 |
每递归一次就算出相应的结果。 |
不能优化成循环 |
能够优化成循环 |