Hanoi Tower汉诺塔问题函数递归算法分析及相应python代码

函数递归应用中最经典的案例要算是汉诺塔(Hanoi Tower)问题了。

题目如下:

  相传印度有一个梵,塔内有三个座A、B、C。A座上有n个盘子,盘子从上到下一个比一个大,最大的在下面。目标:僧人要把这些盘子从A座移到C座,中间借用B座,每次只能移动一个盘子,并且在移动过程中必须始终保持 大盘在小盘的下面。计算不同数量时的移动过程。


分析,既然有第n个盘子,那就有第1个盘子,把盘子从上到下顺序编号为1....n

那么,最底下的第n号盘子就交给方丈了,其他盘子由大师兄全权负责,具体是:

由大师兄负责先把前面n-1个盘子由A移动到B,然后方丈把第n号盘子轻松从A移到C,然后再由大师兄负责把前面n-1个盘子由B移动到C即完成;

那么,大师兄也想了一下,自己就只管第n-1号盘子由A移到B,其他n-2个盘子全交给二师兄去办,具体是:

由二师兄负责先把前面n-2个盘子由A移动到C,然后大师兄轻松把第n-1号盘子从A移到B,然后再由二师兄负责把前面n-2个盘子由C移动到B即完成;

那么,二师兄又想了一下,人家都可以那样干,自己也可以找人啊,于是,每个人都这样想,最后方案简化为每个人都只需做三步:

让别人把其他盘子移到临时座上,自己把最后一个盘子移到自己的目标座,让别人把其他盘子从临时座上移到目标座

这样就形成了递归,每次函数内只做这三件事。

但是递归必须有一个终止条件,终止条件就是最后一个小师弟发现自己就是最后一个了,n=1,那没法再找别人了!自己把盘子乖乖移到目标座吧,没办法了,就相当于本来就只有一个盘子,直接从A移到C,直接返回并结束。

用python代码实现如下:

def hanoi(n, a, b, c):

    if n == 1:
        print("[%02d]:%s->%s" % (n, a, c))
        return
    hanoi(n - 1, a, c, b)
    print("[%02d]:%s->%s" % (n, a, c))
    hanoi(n - 1, b, a, c)


hanoi(3,"a","b","c")
print("done!")

结果如下:

[01]:a->c
[02]:a->b
[01]:c->b
[03]:a->c
[01]:b->a
[02]:b->c
[01]:a->c
done!

加上步数显示,优化代码如下:

cnt = 0


def hanoi(n, a, b, c):
    """
    print move info
    :param n: the plate number
    :param a: the first stick label
    :param b: the second stick label
    :param c: the third stick label
    :return: null
    """
    global cnt

    if n == 1:
        cnt += 1
        print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
        return
    hanoi(n - 1, a, c, b)
    cnt += 1
    print("No.%03d [%02d]:%s->%s" % (cnt, n, a, c))
    hanoi(n - 1, b, a, c)


hanoi(3,"a","b","c")
print("done!")
结果如下:

No.001 [01]:a->c
No.002 [02]:a->b
No.003 [01]:c->b
No.004 [03]:a->c
No.005 [01]:b->a
No.006 [02]:b->c
No.007 [01]:a->c
done!





猜你喜欢

转载自blog.csdn.net/mmhh3000/article/details/78869785