关于递归的思考(1)

关于递归的思考 (1)

大事化小

把一个大的难题演化, 变成相同的难题,但规模缩小。如此重复,直到最后可解。 如, 求阶乘factorial(5):

def factorial(x):
      if x == 1:
          return 1
      else:
          return x * factorial(x - 1)


factorial(5)

如上面的代码 factorial(5)先规模缩小:

3次循环后的结果:
return 4 * factorial(4 -1)
return 3 * factorial(3 -1)
return 2 * factorial(2 -1)
再次运行时:factorial(1)
return 1

规模缩小到factorial(1),问题解决;

怎样把大象放进冰箱?

怎样把大象放进冰箱?这是小品里,宋丹丹问赵本山的脑筋急转弯。 答案出奇简单,是分三步:

1 把冰箱门打开
2 把大象放进去
3 把门关上

让我们回到大学里数据结构的经典问题“汉诺塔”. 64个大小不一大黄金盘子,从A柱子移动到C柱子。 解决步骤:

1 把A柱上面63个盘子看作一个整体,先移动B柱子
2 把A柱第64个盘子移动到C柱
3 把B柱的63个盘子一同移到C柱
def hanoi(n, a='A', b='B', c='C'): 
    if n == 1:              #2.把A柱第64个盘子移动到C柱
        print('move', a, '-->', c) 
        return

    hanoi(n-1, a, c, b)  #1.把A柱上面63个盘子,先移动B柱子
    print('move', a, '-->', c)
    hanoi(n-1, b, a, c) #3.把B柱的63个盘子一同移到C柱

print(hanoi(64))

我们把难题缩到最小, 如果不是64个盘子,而是只有2个,大家在去看上面的代码hanoi输出:

move A ---> B //先把上面的盘子移动B柱
move A ---> C //再把剩下的一个盘子移动到C柱子。
move B ---> C //然后把B柱上的盘子移动C柱。

没有问题, 大家应该能想清楚。现在大家的疑问是:当盘子是64个时,

把A柱上面63个盘子先移动B柱子 行的通吗? 我觉得可以这样想,要把63盘子移动到B柱子, 先要把前面的62个移动开。问题又回来了, 要把第62个盘子移开,先要把前面的61个移动开…. 我们已经知道只有2个盘子的情况,是可行的。 那么数学归纳法应该可以证明的,可惜笔者的数学能力有限。

总结

大事化小,把一个大的问题规模缩小,直至最后能求解,是递归的重要思考方式,各位在日常的编程中可多试试, 几行代码就能把问题解决,简洁优美。

打赏

取消

Buy me a coffee!

扫码支持
扫码支持

感谢您的支持,作者会努力分享更多