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二叉树遍历的实现方法
Nov 21 Python
python3读取MySQL-Front的MYSQL密码
May 03 Python
Flask框架web开发之零基础入门
Dec 10 Python
pandas进行时间数据的转换和计算时间差并提取年月日
Jul 06 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
Aug 13 Python
python 用 xlwings 库 生成图表的操作方法
Dec 22 Python
Python Selenium截图功能实现代码
Apr 26 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
May 24 Python
Python-openpyxl表格读取写入的案例详解
Nov 02 Python
详解Python中@staticmethod和@classmethod区别及使用示例代码
Dec 14 Python
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
Apr 24 Python
baselines示例程序train_cartpole.py的ImportError
May 20 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 mssql 分页SQL语句优化 持续影响
2009/04/26 PHP
PHP中通过加号合并数组的一个简单方法分享
2011/01/27 PHP
php 数组排序 array_multisort与uasort的区别
2011/03/24 PHP
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
WebQQ最新登陆协议的用法
2014/12/22 PHP
PHP7基于curl实现的上传图片功能
2018/05/11 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
offsetParent 算法分析
2010/04/05 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
jQuery代码实现图片墙自动+手动淡入淡出切换效果
2016/05/09 Javascript
简单的分页代码js实现
2016/05/17 Javascript
使用jquery获取url及url参数的简单实例
2016/06/14 Javascript
AngularGauge 属性解析详解
2016/09/06 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
微信小程序 Button 组件详解及简单实例
2017/01/10 Javascript
js实现无缝滚动图(可控制当前滚动的方向)
2017/02/22 Javascript
基于JavaScript定位当前的地理位置
2017/04/11 Javascript
jstree单选功能的实现方法
2017/06/07 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
微信接入之获取用户头像的方法步骤
2019/09/23 Javascript
JS监听组合按键思路及实现过程
2020/04/17 Javascript
python实现计算倒数的方法
2015/07/11 Python
Python3爬虫学习之MySQL数据库存储爬取的信息详解
2018/12/12 Python
Python 多线程搜索txt文件的内容,并写入搜到的内容(Lock)方法
2019/08/23 Python
Mysql数据库反向生成Django里面的models指令方式
2020/05/18 Python
Python读写压缩文件的方法
2020/07/30 Python
日本7net购物网:书籍、漫画、杂志、DVD、游戏邮购
2017/02/17 全球购物
应聘教师推荐信
2013/10/31 职场文书
统计系教授推荐信
2014/02/28 职场文书
事业单位分类改革实施方案
2014/03/21 职场文书
三八妇女节活动总结
2014/05/04 职场文书
学校班子个人对照检查材料思想汇报
2014/09/27 职场文书
导游词之包公祠
2019/11/25 职场文书