一、首先来简单介绍一下递归和尾递归
1.递归:
简单来说就是在函数内部调用函数本身来完成函数体。对于返回值的要求并不很严格。
递归的缺点:递归效率比较低,调用次数过多还会出现栈溢出的问题。
2.尾递归:
尾递归的核心思想:通过参数来传递每一次的调用结果,达到不压栈。它维护着一个迭代器和一个累加器。
递归函数的返回值是递归函数表达式
其实与循环的思想类似,每次调用此函数(进栈),调用完成不用在栈里面等着,可以直接出栈,调用结果在累加器被记录,不存在栈溢出的情况。
二、下面来用例子来加深一下理解
题目:
写一个递归函数,来获取第n个斐波那契数,前两个斐波那契数0 和 1,第n个数总是等于前两个数的和
序列开始为0,1,1,2,3,5.
请定义尾递归函数 def fib(n: Int): Int
1.fibonacci的递归形式
object Fibonacci {
def fib(n:Int):Int={//定义递归函数,返回第n个fibonacci数
if(n==1){//定义第1个和第2个fib数
return 0
}
if (n==2){
return 1
}
fib(n-1)+fib(n-2)
}
def main(args: Array[String]): Unit = {
println(fib(5))
}
}
2.fibonacci尾递归形式
import scala.annotation.tailrec
/*
实现思路:利用循环的思想将递归转化为尾递归的形式
在函数内定义递归函数(这个是尾递归的,用三个参数来进行计算)
第一个是n,相当于迭代器,第二和第三个相当于从递归内部向外开始计算的累加器(fib数)
*/
object Fibonacci {
def fib(n:Int):Int={//定义递归函数,返回第n个fibonacci数
@tailrec
def fibonacci(n:Int,current:Int,next:Int):Int={
if(n==1){//这个是为了单独列出当n为1时的情况
current
}else if(n==2){//当n>2时执行到此处就会返回结果值(索引递减,但是递归是向外)
next
}else{
fibonacci(n-1,next,current+next)
}
}
fibonacci(n,0,1)//定义第1个fib数和第二个fib数
}
def main(args: Array[String]): Unit = {
println(fib(5))
}
}
运行结果: