在递归中,合理的边界条件是避免程序无限递归的关键。以下代码对递归函数的边界做了更严谨的处理。
scala
object ffff {
def f(n:Int):Int = {
if(n == 0){
1
} else if(n > 0) {
f(n - 1) + f(n - 2)
} else {
0 // 处理n为负数的边界情况
}
}
def main(args: Array[String]): Unit = {
val rst = f(2)
println(rst)
}
}
- 逻辑解析:除了处理
n=0的情况,还新增了对n<0的判断,返回默认值0,保证函数在任何整数输入下都能正常运行。 - 运行结果:调用
f(2)时,按照f(2)=f(1)+f(0),f(1)=f(0)+f(-1),最终结果为1 + 1 + 0 = 2(此处f(1)的计算因n>0进入递归,f(0)返回 1,f(-1)返回 0)。
汉诺塔问题的递归求解(ggg.scala)
汉诺塔问题是递归算法的经典难题,规则是:有三根柱子,将n个盘子从一根柱子借助另一根柱子移动到第三根柱子,且每次只能移动一个盘子,大盘不能压小盘。
scala
object ggg {
/**
* 汉诺塔,递归
*/
var i = 1;
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")
}
}
-
逻辑解析:
- 当
n=1时,直接将盘子从 A 移动到 C。 - 当
n>1时,分三步:首先将n-1个盘子从 A 借助 C 移动到 B;然后将第n个盘子从 A 移动到 C;最后将n-1个盘子从 B 借助 A 移动到 C。
- 当
-
运行结果:对于 4 个盘子的汉诺塔问题,程序会输出 15 步移动过程(如 “1, move 1 from A -> C”“2, move 2 from A -> B” 等),这符合汉诺塔移动步数公式
2^n - 1(n=4时,2^4 -1=15)。
递归的核心思想与总结
递归的核心在于 “分而治之” ,将复杂问题分解为规模更小的同类子问题,直到子问题可以直接解决(边界条件)。通过以上三个案例可以看出:
- 斐波那契数列体现了递归的基本形式,通过自身调用来累加结果。
- 带边界处理的递归函数强调了 “边界条件完整性” 对递归稳定性的重要性。
- 汉诺塔问题则展示了递归在解决复杂逻辑问题时的强大能力,将看似繁琐的移动步骤抽象为简洁的递归逻辑。