递归的本质:整体思想

  • 代码写到一定程度,一定会使用到递归。比如使用java遍历一个文件夹中,所有的文件及文件夹,及子文件夹中的所有文件及文件夹。

  • 经典的汉诺塔问题,是一个必须使用递归才能解决的问题。

    汉诺塔(港台:河内塔)是根据一个传说形成的数学问题:
    有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
    每次只能移动一个圆盘;
    大盘不能叠在小盘上面。
    提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。
    问:如何移?最少要移动多少次?


解决思路:
  • n=1 时,直接移动过去即可。

  • n=2 时,就需要分步骤移动了:

    • 第一次 从 A 移动到 B
    • 第二次 从 A 移动到 C
    • 第三次 从 B 移动到 C
  • n=k 时,依然是分步骤移动:不过在这里,是将 k-1 个盘子,全部当成一个整体。也就是当成第二个盘子。第一个盘子,仍然是第一个。这样就可以使用 n=2 时到方式,完成 n=k 时到移动逻辑。

通过上述到解决思路,这个汉诺塔问题就可以解决了。至于使用什么语言,都是次要的。这里给出两个版本的代码

  • python 版本
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @name   : hannuo.py
# @author : cat
# @date   : 2017/7/19.


class HanNuo:
    def __init__(self):
        self.step = 0
        pass

    def move(self, n, x='x', y='y', z='z'):
        if n == 1:
            self.step += 1
            print("step = {} , move {} from {} to {}".format(self.step, n, x, z))
            return
        else:
            self.move(n - 1, x, z, y)
            self.move(1, x, y, z)
            self.move(n - 1, y, x, z)

#
# def move(n, x='x', y='y', z='z'):
#     if n == 1:
#         print(" move {} from {} to {}".format(n, x, z))
#         return
#     else:
#         move(n - 1, x, z, y)
#         move(1, x, y, z)
#         move(n - 1, y, x, z)


if __name__ == '__main__':
    # move(4)
    print("-" * 24)
    h = HanNuo()
    h.move(3)
    pass
  • Java 版本

/**
 * Created by cat on 2017/7/19.
 */
public class HanNuo {

    public static void main(String[] args) {
        int n = 3;

        Han han = new Han();

        han.move(n, "x", "y", "z");
        System.out.printf("move %s need %s times", n, han.count);

    }


}

class Han {
    public int count = 0;

    public void move(int n, String x, String y, String z) {
        if (n == 1) {
            count += 1;
            System.out.printf("move from %s to %s \n", x, z);
        } else {
            move(n - 1, x, z, y);
            move(1, x, y, z);
            move(n - 1, y, x, z);
        }
    }
}
  • c++ 版本
#include <iostream>

void hanNuo(int n, char x, char y, char z);

using namespace std;

int main() {
    int n = 3;
    char x = 'x';
    char y = 'y';
    char z = 'z';
    cout << "count = " << n << " start hanNuo..." << endl;
    hanNuo(n, x, y, z);
    cout << "count = " << n << " end hanNuo  ###" << endl;

    return 0;
}

int step = 0;

void hanNuo(int n, char x, char y, char z) {
    if (n == 1) {
        step += 1;
        cout << "step " << step << ": move from " << x << " to " << z << endl;
    } else {
        hanNuo(n - 1, x, z, y);
        hanNuo(1, x, y, z);
        hanNuo(n - 1, y, x, z);
    }

}

输出如下:

count = 3 start hanNuo...
step 1: move from x to z
step 2: move from x to y
step 3: move from z to y
step 4: move from x to z
step 5: move from y to x
step 6: move from y to z
step 7: move from x to z
count = 3 end hanNuo  ###

Process finished with exit code 0

ps: 千万不要尝试 n=64 的情况,容易死机。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值