数据结构与算法Python版 递归的应用


一、递归应用-十进制转换任意进制

一个十进制整数,实现从二进制到十六进制的任意进制转换。采用递归三定律分析:

  • 用整数除和求余数,两个计算来将任意十进制数一步步拆开。除以“进制基base”(// base)得到商,对“进制基”求余数(% base)
  • 基本结束条件:余数总小于“进制基base”,是“基本结束条件”,可直接进行查表转换
  • 减少问题规模并调用自身:商成为“更小规模”问题,通过递归调用自身解决
def decimal_to_base(decimal_number, base):
    digits = "0123456789ABCDEF"

    if decimal_number < base:
        return digits[decimal_number]
    else:
        # +号实现字符串拼接,两者顺序不能互换
        return (
            decimal_to_base(decimal_number // base, base)
            + digits[decimal_number % base]
        )


print(decimal_to_base(60, 2))
print(decimal_to_base(60, 8))
print(decimal_to_base(60, 16))


### 输出结果
111100
74
3C

二、递归应用-汉诺塔

汉诺塔

  • 汉诺塔问题是法国数学家Edouard Lucas于1883年,根据传说提出来的
  • 有3根柱子,其中一根套着64个由小到大的黄金盘片,要把这一叠黄金盘从一根柱子搬到另一根,但有两个规则:
    • 一次只能搬1个盘子
    • 大盘子不能叠在小盘子上

在这里插入图片描述

分析

  • 假设我们有5个盘子,穿在1#柱,需要挪到3#柱
    • 想办法把最上面4个盘子挪到2#柱,那问题就好解决了:把剩下的最大号盘子直接从1#柱挪到3#柱。再用同样的办法把2#柱上的4个盘子挪到3#柱,就完成了整个移动
  • 接下来问题就是解决4个盘子如何能从1#挪到2#?此时问题规模已经减小!
    • 想办法把最上面3个盘子挪到3#柱,把剩下最大号盘子从1#挪到2#柱。再用同样的办法把3个盘子从3#挪到2#柱
  • 接下来问题就是解决3个盘子如何能从1#挪到3#?此时问题规模已经减小!
    • 想办法把最上面2个盘子挪到2#柱,把剩下最大号盘子从1#挪到3#柱。再用同样的办法把2个盘子从2#挪到3#柱
  • 接下来问题就是解决2个盘子如何能从1#挪到2#?此时问题规模已经减小!
    • 把最上面1个盘子挪到3#柱,把剩下最大号盘子从1#挪到2#柱。再把1个盘子从3#挪到2#柱

在这里插入图片描述

递归思路

  • 将盘片塔从开始柱,经由中间柱,移动到目标柱:
  • 首先将上层N-1个盘片的盘片塔,从开始柱,经由目标柱,移动到中间柱;然后将第N个(最大的)盘片,从开始柱,移动到目标柱;最后将放置在中间柱的N-1个盘片的盘片塔,经由开始柱,移动到目标柱。
  • 基本结束条件,也就是最小规模问题是:1个盘片的移动问题
### 汉诺塔问题
def move_tower(level, from_pole, with_pole, to_pole):
    if level > 0:  # 结束条件
        # 上层N-1个盘片的盘片塔,从开始柱,经由目标柱,移动到中间柱
        move_tower(level - 1, from_pole, to_pole, with_pole)  #
        # 将第N个(最大的)盘片,从开始柱,移动到目标柱
        move_disk(level, from_pole, to_pole)
        # 将放置在中间柱的N-1个盘片的盘片塔,经由开始柱,移动到目标柱
        move_tower(level - 1, with_pole, from_pole, to_pole
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值