Python递归及尾递归优化操作实例分析


Posted in Python onFebruary 01, 2020

本文实例讲述了Python递归及尾递归优化操作。分享给大家供大家参考,具体如下:

1、递归介绍

递归简而言之就是自己调用自己。使用递归解决问题的核心就是分析出递归的模型,看这个问题能拆分出和自己类似的问题并且有一个递归出口。比如最简单的就5的阶乘,可以把它拆分成5*4!,然后求4!又可以调用自己,这种问题显然可以用递归解决,递归的出口就是求1!,可以直接返回1。用Python实现如下:

def fact(n):
  if n==1:
    return n
  return n*fact(n - 1);
print(fact(5))

运行结果:

120

2、尾递归优化

在上面的求递归中,也有一定的缺点,假如说求1000!的阶乘,会出现栈溢出的问题,因为在函数执行中,没调用一个函数都会把当前函数的调用位置和内部变量保存在栈里面,由于栈的空间不是无限大(具体栈的最大空间还没有查找到),假如说调用层数过多,就是出现栈溢出的情况。

这个时候就可以用尾递归优化来解决,尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。

function f(x){
 return g(x);
}

尾递归优化后的阶乘函数如下:

def fact(n):
  return fact_iter(n,1);
def fact_iter(num, product):
  if num == 1:
    return product
  return fact_iter(num - 1, num * product)
print(fact(5))
print(fact(1000))

尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了。所以尾递归优化可以有效的防止栈溢出,但是尾递归优化需要编译器或者解释器的支持,遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

3、汉诺塔问题

汉诺塔问题也是一个经典的递归问题,具体题目就不说了,这里分析思路。假设hanoi(n, a, b, c)实现把a上的n个盘子移到c上。

当只有一个盘子时,直接从A移动到C即可

如果有3个盘子,可以这样:

# A --> C
# A --> B
# C --> B
# A --> C
# B --> A
# B --> C
# A --> C

如果有很多盘子,我们分析一下该怎么移动,首先,我们需要把n-1个盘子移动到b中,才可以实现最简单的一步,把a中最大的盘子移动到c中,具体怎么转移到b中后面再讨论。移动最大的盘子后,a和c都可以看成是空的,接下来,把b看成是a,把a看成是b,把a中的n-1个盘子(这里的n是已经减1的n)移动到b后,又可以移动第二大的盘子。这显然是一个递归问题。

递归的出口就是n等于1,直接从a移动到c即可。

那么怎么接下来讨论,怎么把n-1个盘子移动到b,这不又是一个递归问题嘛!可以调用它自己呀,只不过需要把b看成是c,把c看成是b。所以代码如下:

def hanoi(n,a,b,c):
  #只有一个盘子,直接移动
  if n==1:
    print(a,'->',c)
  else:
    #通过c把n-1个盘子移动到b
    hanoi(n-1, a,c,b)
    #移动最大的盘子
    print(a,'->',c)
    #通过a把n-1个盘子移动到c
    hanoi(n-1, b,a,c)
hanoi(3,'A','B','C')

运行结果:

A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C

转自https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431756044276a15558a759ec43de8e30eb0ed169fb11000

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python通过apply使用元祖和列表调用函数实例
May 26 Python
python妹子图简单爬虫实例
Jul 07 Python
Python中turtle作图示例
Nov 15 Python
对TensorFlow的assign赋值用法详解
Jul 30 Python
python 格式化输出百分号的方法
Jan 20 Python
基于SQLAlchemy实现操作MySQL并执行原生sql语句
Jun 10 Python
浅谈Python爬虫原理与数据抓取
Jul 21 Python
Python os库常用操作代码汇总
Nov 03 Python
appium+python自动化配置(adk、jdk、node.js)
Nov 17 Python
PyCharm 安装与使用配置教程(windows,mac通用)
May 12 Python
Python数据分析之pandas读取数据
Jun 02 Python
python3 字符串str和bytes相互转换
Mar 23 Python
Python异步编程之协程任务的调度操作实例分析
Feb 01 #Python
python随机生成大小写字母数字混合密码(仅20行代码)
Feb 01 #Python
Python random模块制作简易的四位数验证码
Feb 01 #Python
python模拟预测一下新型冠状病毒肺炎的数据
Feb 01 #Python
Python warning警告出现的原因及忽略方法
Jan 31 #Python
Python 2种方法求某个范围内的所有素数(质数)
Jan 31 #Python
PyQt5中多线程模块QThread使用方法的实现
Jan 31 #Python
You might like
php 全文搜索和替换的实现代码
2008/07/29 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
PHP中使用asort进行中文排序失效的问题处理
2014/08/18 PHP
php过滤表单提交的html等危险代码
2014/11/03 PHP
TP3.2.3框架使用CKeditor编辑器在页面中上传图片的方法分析
2019/12/31 PHP
MSN消息提示类
2006/09/05 Javascript
javascript 获取图片颜色
2009/04/05 Javascript
AJAX使用了UpdatePanel后无法使用alert弹出脚本
2010/04/02 Javascript
ExtJS[Desktop]实现图标换行示例代码
2013/11/17 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
js通过元素class名字获取元素集合的具体实现
2014/01/06 Javascript
深入理解JavaScript编程中的同步与异步机制
2015/06/24 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
原生js实现autocomplete插件
2016/04/14 Javascript
javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
2016/08/19 Javascript
BootStrap table表格插件自适应固定表头(超好用)
2016/08/24 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
JavaScript实现新年倒计时效果
2018/11/17 Javascript
Vue 权限控制的两种方法(路由验证)
2019/08/16 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
[02:39]我与DAC之Newbee.Moogy:从论坛到TI
2018/03/26 DOTA
[46:20]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第二场 1月22日
2021/03/11 DOTA
python Pandas 读取txt表格的实例
2018/04/29 Python
Sanic框架基于类的视图用法示例
2018/07/18 Python
详解Python中的format格式化函数的使用方法
2019/11/20 Python
pytorch 模拟关系拟合——回归实例
2020/01/14 Python
python 计算方位角实例(根据两点的坐标计算)
2020/01/17 Python
在 Python 中接管键盘中断信号的实现方法
2020/02/04 Python
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
家得宝官网:The Home Depot(全球最大的家居装饰专业零售商)
2018/12/17 全球购物
《掌声》教学反思
2014/02/23 职场文书
护士长竞聘演讲稿
2014/04/30 职场文书
大学新生入学教育方案
2014/05/16 职场文书
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python
Spring IOC容器Bean的作用域及生命周期实例
2022/05/30 Java/Android