Python实现汉诺塔递归经典算法

廖大神学习网站上学到递归的时候,有这样一个练习:
《Python实现汉诺塔递归经典算法》
题目:请编写move(n, a, b, c)函数,它接收参数n,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法,
期待输出:
A –> C
A –> B
C –> B
A –> C
B –> A
B –> C
A –> C
这篇文章对这个学习做一个总结。

代码敬上

简洁版:

def move(n, a, b, c):
    if n==1:
        print(a,'-->',c)
        return
    move(n-1,a,c,b) 
    move(1,a,b,c) 
    move(n-1,b,a,c) c
move(3, 'A', 'B', 'C')

按思路注释版

def move(n, a, b, c):
    if n==1: #n值为1 而非定义n=1 
        return print(a,'-->',c)#只有一个盘的时候,a移动到c;
    move(n-1,a,c,b) #(第一步)进入递归,直到n-1==1时,实现a->b 传入递归的参数的n值改变,递归结束后n值恢复,注意传入函数的参数的位置;
    move(1,a,b,c) #(第二步)接着执行,调用自身函数实现a->c,可替换为print(a,'->',c),因为只是将A柱底最大盘移至C柱的过程(第二步); 
    move(n-1,b,a,c) #(第三步)将位于b处的n-1个盘从b经由a移至c ,上一个递归后n恢复为调用函数传入的n,进入递归,实现b->c;
move(3, 'A', 'B', 'C')

首先,汉诺塔移动的原理
汉诺塔是将所有盘子(n个)从A柱挪至C柱,大盘必须在小盘下方。注意却分思路和具体步骤。

思路

为将n-1个盘子(除了最底下一枚)从A移到B(第一步); 然后将位于A的最后一枚最大盘移至C(第二步); 再将B柱上所有盘移至C柱(第三步)。

具体步骤便是需要实现上面第一步,要实现第一步又要先移动(n-1)上面的(n-1)-1个盘子,所以这是典型的递归原理。
注:刚开始我混淆了思路与具体步骤,想到了具体步骤但看思路的时候发现与每次只能移动一个要求不同,原因是步骤是上往下移动从开始到结果,而递归是从结果到开始得到最小值,再从开始到结果。
《Python实现汉诺塔递归经典算法》
最小的子问题就是:将一块盘子从A移动到C柱,“大于1”的子问题是:将两块盘子从A移动到C柱,不妨在草稿纸上画个图,显然有三个步骤:

1.将最上面的盘子从A移动到B

2.将A下面的盘子从A移动到C

3.将B上的盘子移动到C

而程序调用自身则是逐次对(n-1)个盘子进行同样的操作就可以解决n个盘子移动的问题。
只需以上三步分析就能得到这个递归程序的全部求解过程。

代码实现具体查看按思路注释版

注:值得注意的是函数执行的顺序 和参数的含义。

当然如果只是简单,可以推算出规律(2的n次方-1)不用递归。如下代码便可计算:

#汉诺塔递归算法 2的n次方—1
def h(n): #直接计算
    return 2**n-1
print(h(3))

最后输出7.

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/github_40122084/article/details/77914003
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞