最近在复习Python的递归函数部分,突然有了一些小感悟,想赶紧先记录下来,日后再深入思考,完善这篇文章
之前写递归函数的题目总是无从下手。后来我突然联想到高中数学(好像离散数学中也说过),有一个关于递归证明法的介绍,对于一个命题的证明,首先我们得证明某一种特殊情况的成立,其次对于任意一般情况,我们都可以通过“迭代”慢慢趋向到这个特殊情况上,这样这个命题便证明成功。
那和递归函数有什么联系?我观察到,每一个递归函数解法都是不断迭代到一个特殊点去解决,然后再不断回溯完成整个流程。也就是说,对于任意一道递归函数的算法题,我们首先应该需要找到这个特殊情况,即处于终结点我们将不再继续迭代下去。另一个思考地方是如何让一般情况趋向特殊情况,最后思考如何处理回溯的元素(思考倒数第二个情况比较容易)
我举个例子:
题目很简单:使用递归算法将一个字符串反转。
首先我们思考,终结情况是什么?
应该是最后一个字符,当遇到最后一个字符时候我们应该立马输出,停止继续迭代
当遇到其他字符的时候我们应该让他在身后字符先输出
def reverseStr(str1,i):#这里i的作用要注意,调用时候传递0进去,表示从字符串首元素开始
#先判断特殊情况
if i=len(str1)-1:
print(str1[i],end="")
else:#对于一般情况的处理,我们只要思考倒数第二位如何处理就好
reverseStr(str1,i+1)#为什么要i+1,因为要趋向终结情况
print(str1[i],end="")#处理回溯,倒数第一输出完成后,我们就要输出倒数第二了
对于经典的汉诺塔问题
依然,我们首先找特殊情况,当某一个块为最顶端的块时(特殊情况),他直接移动就好(不迭代)
当一个块不是最顶端的块的时候(一般情况),我们就需要将他上面的块堆移动到另一个柱子上(趋向方法)
当上面的块堆移动完成,他就可以完成移动了 (处理回溯)
def Hanoi(num,a,b,c):#把num个方块从a移动到c
if num==1:#特殊情况,块在最顶端,直接移动
print("盘{0} 从{1}柱-->柱{2}".format(num,a,c)) # 打印移动情况
else:
Hanoi(num-1,a,c,b)#一般情况,迭代到他上面的块,注意实参的位置变化
print("盘{0} 从{1}柱-->柱{2}".format(num,a,c)) # 打印移动情况
Hanoi(num-1,b,a,c)#处理回溯,开始考虑倒数第二块,要将倒数第二块从b移动到c
n=int(input("请输入汉诺塔的块数:"))
Hanoi(n,'A','B','C')
记录一下,还要接着复习备考,就先不深入探讨了
思维难免有疏漏,幼稚之处,所以大佬们有什么意见一定要提出来,我们一起讨论一起进步!
2021.8.31更
最近复习数据结构,在树、二叉树的遍历算法这里折腾了好久,对递归算法又有了一些新的小感悟,赶紧记录下。
一种递归是:将复杂问题一层一层分解到一个已知的简单问题,最后再通过函数的返回值一层一层叠加回去。
还有一种不需要回溯,用一种替代的方法,比方二叉树的遍历,从根节点开始,每次遍历都把子树看作是一个结点。
阿西吧,我发现我好难把自己的想法用语言描述出来,,还是理解不够透彻。。。