Python数据结构与算法——第四课 俄罗斯套娃与递归

  俄罗斯套娃(俄语:матрёшка),是俄罗斯民族特色的木制玩具,一般由多个一样图案的空心木娃娃一个套一个组成,最多可达十多个,通常为圆柱形,底部平坦可以直立。如果不太了解俄罗斯套娃是什么,请打开下面的俄罗斯套娃3D视频观看。

  格物致知,你从俄罗斯套娃视频中感悟到了什么呢?也许有,但无法用语言表达出来。不要紧,俄罗斯套娃的思想投影到数学里就是化归思想了。

  化归思想:一个大问题想不出解决办法,但知道同类的规模较小的问题的解决办法,于是尝试把问题减少一个单位,解决变化情况,如此类推,直到能解决的程度。

  化归思想也可以直接解决数学问题。例如,求前n个奇数和:

1+3+5+....+[2(n-1)+1]=?

  首先,我们知道,前1个奇数的和是1,这个问题可以用化归思想解决。先把问题转化为:

{1+3+5+....+[2(n-2)+1]}+[2(n-1)+1]=?

  显然,大括号里的问题是原问题的套娃,因此只需要解决[2(n-1)+1]项的问题。把它转化为:

2(n-1)+1 = (n-1) + 1 +(n-1)

  根据数形结合,上面整式可以用下面的图形表示:

 

  看了上图后,你应该得到了答案:

1+3+5+....+[2(n-1)+1]=n²

  数学化归思想应用到编程,就是递归

  下面先编写一个Python程序验证上面的结果。

  运行结果:

 

  练习题1用化归思想推导下面式子的公式,然后编写Python递归程序验证。

1+7+...+[3(n-1)²+3(n-1)+1]=?

  练习题2用化归思想推导(凸)n(n≥3)边形内角和公式,然后编写Python递归程序验证。

 

  我们日常生活中的套娃从前有座山,山里有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么故事?从前有座山,山里有座庙,庙里有个老和尚在给小和尚讲故事,讲的什么故事?从前有座山……”。这种套娃和俄罗斯套娃有什么区别?

  第一点,套娃没有结束条件,俄罗斯套娃受加工条件限制,最多十多个;

  第二点,套娃的每次copy没有缩小规模,俄罗斯套娃要套在里面,所以要越来越小。

  显然,这个故事不符合俄罗斯套娃思想,也就是数学的化归思想,当然不是递归了。

  在《Python算法图解》中提出把这故事改编为递归的故事,原文如下:

  这个例子近似于递归现象,但是严格来说并不是递归,因为该例子会一直重复下去,没有终止条件,那就成了死循环。加个条件,就成了递归。例如:从前有座山,山里有座庙,庙里有个老和尚和小和尚,如果小和尚没睡着,老和尚就讲故事;从前有座山,山里有座庙如果小和尚睡着了,老和尚就停止讲故事(这时递归调用就停止了)。

  虽然加了结束条件,但每次copy没有缩小规模,从严格意义上来说,还不是递归。

  从编程方面来说,计算机是无法理解所谓规模的,递归算法只是程序中的函数(有返回值)或过程(无返回值函数)调用自身的编程技巧。调用自身的过程,如果没有有效的终止调用自身的条件——“,最终会产生程序堆栈溢出错误。设置有效的终止条件是程序员的责任,计算机帮不上忙。设置有效的终止条件方法如下:

  第一步:选定条件变量;

  第二步:条件变量在函数调用自身时如何变化;

  第三步:构建条件表达式;

  第四步:判断条件是否能达到和不总是达到。

  例题1输入12≤n≤64的正整数n,用递归法计算1/2+1/4+1/8+...直到最后一项≤1/n的和。

  分析:第一步,选定数列的项序数(1,2,3,......)为条件变量;第二步,函数调用自身时条件变量增加1;第三步,根据最后一项≤1/n的条件,得条件表达式pow(2, 条件变量)>=n;第四步,随着项序数增加,pow(2, 条件变量)增大,最终一定会超过或达到n

  程序编码:

 

  运行结果:

 

  练习题3如果把例题1的代码改为下图的样子,请完善代码。

 

 

  递归代码虽然简单,但它是内存吃货,甚至会把电脑卡死。因为每次递归调用都要把现场压入运行堆栈,如果现场状态太多或递归次数太大,还没到递归终止,运行堆栈就溢出了。所以,除非其他方法(例如循环)无法实现才采用递归算法,而且尽量使递归部分简单,设置限制范围使递归的次数尽量少。

  最后,把上面故事改成下面这样更符合递归:

  从前有座山,山里有片树林,风吹着树林沙沙作响,树林里有座庙,庙里有个老和尚在给小和尚讲故事,声音越来越小,越来越慢,最后湮没在风声中就停止了,讲的是什么故事呢?从前有座山,山里有片树林,风吹着树林沙沙作响,树林里有座庙,庙里有个老和尚在给小和尚讲故事,声音越来越小,越来越慢,最后湮没在风声中就停止了,讲的是什么故事呢?从前有座山,......

 

参考资料:

1、强基初中数学&Python——第十六课 套娃多项式探究

2、强基初中数学&Python——136课 多边形、化归思想与递归算法

3、《Python算法图解》何韬编著 清华大学出版社