递归函数的定义和格式
递归是一种常用的解决问题的方法,特别适用于解决可以被分解为类似子问题的问题。递归函数通常由两个主要部分组成:起始条件(或基线条件)和递归规则(或递归关系)。
起始条件:一个递归的终止条件,确保递归不会无限进行。它处理最简单的情况并返回结果。
递归规则:在这个部分,函数会调用自身,以解决一个更小的子问题。
/**
* 递归:在函数内部 自己调用自己
*
* 特点:
* 1.可能会导致死循环:一直调用自己
*/
def f():Unit = {
println("f函数被调用了......")
f()
}
def main(args: Array[String]): Unit = {
f()
// while(true){
// println("f函数被调用了......")
// }
println("main")
}
案例
1.计算累加
计算一个整数的累加是一个经典的递归问题。假设我们要计算 n 的累加和,记作 f(n) = 1 + 2 + 3 + ... + n
/**
* 递归函数的应用场景
*
* 特点:
* 1.大问题可以拆解为同样性质的小问题
* 2.问题拆解到足够小的时候,可以直接求解
*
* 举例
* 大任务:求1+2+3+...+99+100的和(5050)
* 记f(n)=1+2+3+4+...+n
* f(100)=1+2+3+...+98+99+100
* f(99)=1+2+3+...+98+99
* f(98)=1+2+3+...+98
*
*f(100)=f(99)+100
* f(99)=f(98)+99
* ......
* f(1)=1(足够小的时候,可以直接求解)
* f(n)=f(n-1)+n
*/
def f(n:Int):Int={
if(n == 1){
1
}else{
f(n-1)+n
}
}
def main(args: Array[String]): Unit = {
val rst=f(100)
println(rst)
}
2.整数的阶乘
计算一个整数的阶乘是一个经典的递归问题。假设我们要计算 n 的阶乘,记作 n!=123*4...*n
/**
* 递归函数的应用场景
*
* 特点:
* 1.大问题可以拆解为同样性质的小问题
* 2.问题拆解到足够小的时候,可以直接求解
*
* 举例
* 记f(n)=1*2*3*4*...*n
* ......
* f(1)=1(足够小的时候,可以直接求解)
* f(n)=f(n-1)*n
*/
def f(n:Int):Int={
if(n == 1){
1
}else{
f(n-1)*n
}
}
def main(args: Array[String]): Unit = {
val rst=f(4)
println(rst)
}
3.斐波那契数列
/**
* 求斐波那契数列数据的第n项
*
*
* f(1)=1
* f(2)=2
*
* f(n)=f(n-1)+f(n-2)
*/
def f(n:Int):Int={
//写代码
if(n == 1){
1
}else if(n==2){
2
}else{
f(n-1)+f(n-2)
}
}
def main(args: Array[String]): Unit = {
val rst=f(5)//8
println(rst)
}
4.a的n次方
**
* 求a的n次方,a*a*a......*a(n个a)
*
*
* f(a,o)=1
*
*
* f(a,n)=a*f(a,n-1)
*/
def f(a:Int,n:Int):Int={
//写代码
if(n == 0){
1
}else{
a*f(a,n-1)
}
}
def main(args: Array[String]): Unit = {
val rst=f(2,3)//8
println(rst)
}
5.汉诺塔游戏
/**
* 汉诺塔,递归
*/
var i = 0
def hanoi(n: Int, A: String, C: String, B: String): Unit = {
if (n == 1) {
println(s"$i,move 1 from $A → $C")
i += 1
} else {
hanoi(n - 1, A, B, C)
println(s"$i,move $n from $A → $C")
i += 1
hanoi(n - 1, B, C, A)
}
}
def main(args: Array[String]): Unit = {
//4个盘子 从A移动到C,借助B
hanoi(4, "A", "C", "B")
}