scala

48 阅读2分钟

在递归中,合理的边界条件是避免程序无限递归的关键。以下代码对递归函数的边界做了更严谨的处理。

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 - 1n=4时,2^4 -1=15)。

递归的核心思想与总结

递归的核心在于 “分而治之” ,将复杂问题分解为规模更小的同类子问题,直到子问题可以直接解决(边界条件)。通过以上三个案例可以看出:

  • 斐波那契数列体现了递归的基本形式,通过自身调用来累加结果。
  • 带边界处理的递归函数强调了 “边界条件完整性” 对递归稳定性的重要性。
  • 汉诺塔问题则展示了递归在解决复杂逻辑问题时的强大能力,将看似繁琐的移动步骤抽象为简洁的递归逻辑。