Python基础教程、Python入门教程之递归算法.doc
《Python基础教程、Python入门教程之递归算法.doc》由会员分享,可在线阅读,更多相关《Python基础教程、Python入门教程之递归算法.doc(4页珍藏版)》请在咨信网上搜索。
. . Python基础教程、Python入门教程之递归算法 文章目录1. 递归概述2. 线性递归3. 尾递归4. 单向递归5. 深度优先与广度优先 1. 递归概述递归( recursion)是一种编程技巧,某些情况下,甚至是无可替代的技巧。递归可以大幅简化代码,看起来非常简洁,但递归设计却非常抽象,不容易掌握。通常,我们都是自上而下的思考问题, 递归则是自下而上的解决问题——这就是递归看起来不够直观的原因。那么,究竟什么是递归呢?让我们先从生活中找一个栗子。我们都有在黑暗的放映厅里找座位的经验:问问前排的朋友坐的是第几排,加上一,就是自己当前所处位置的排号。如果前排的朋友不知道自己是第几排,他可以用同样的方法得到自己的排号,然后再告诉你。如果前排的前排的朋友也不知道自己是第几排,他就如法炮制。这样的推导,不会无限制地进行下去,因为问到第一排的时候,坐在第一排的朋友一定会直接给出答案的。这就是递归算法在生活中的应用实例。关于递归,不太严谨的定义是“一个函数在运行时直接或间接地调用了自身”。严谨一点的话,一个递归函数必须满足下面两个条件:至少有一个明确的递归结束条件,我们称之为递归出口,也有人喜欢把该条件叫做递归基。有向递归出口方向靠近的直接或间接的自身调用(也被称作递归调用)。递归虽然晦涩,亦有规律可循。掌握了基本的递归理论,才有可能将其应用于复杂的算法设计中。2. 线性递归我们先从最经典的两个递归算法开始——阶乘(factorial)和斐波那契数列(Fibonacci sequence)。几乎所有讨论递归算法的话题,都是从从它们开始的。阶乘的概念比较简单,唯一需要说明的是,0的阶乘是1而非0。为此,我专门请教了我的女儿,她是数学专业的学生。斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列是这样定义的: F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N,N为正整数集)1阶乘和斐波那契数列的递归算法如下:def factorial(n): if n == 0: # 递归出口 return 1 return n*factorial(n-1) # 向递归出口方向靠近的自身调用def fibonacci(n): if n < 2: # 递归出口 return 1 return fibonacci(n-1) + fibonacci(n-2) # 向递归出口方向靠近的自身调用这两个函数的结构都非常简单,递归出口和自身调用清晰明了,但二者有一个显著的区别:阶乘函数中,只用一次自身调用,而斐波那契函数则有两次自身调用。阶乘递归函数每一层的递归对自身的调用只有一次,因此每一层次上至多只有一个实例,且它们构成一个线性的次序关系。此类递归模式称作“线性递归”,这是递归最基本形式。非线性递归(比如斐波那契递归函数)在每一层上都会产生两个实例,时间复杂度为O(n2) O(n^2)O(n 2),极易导致堆栈溢出。其实,用循环的方法同样可以简洁地写出上面两个函数。的确,很多情况下,递归能够解决的问题,循环也可以做到。但是,更多的情况下,循环是无法取代递归的。因此,深入研究递归理论是非常有必要的。3. 尾递归接下来,我们将上面的阶乘递归函数改造一下,仍然用递归的方式实现。为了便于比较,我们把两种算法放在一起。def factorial_A(n): if n == 0: # 递归出口 return 1 return n*factorial_A(n-1) # 向递归出口方向靠近的自身调用def factorial_B(n, k=1): if n == 0: # 递归出口 return k k *= n n -= 1 return factorial_B(n,k) # 向递归出口方向靠近的自身调用比较 factorial_A() 和 factorial_B() 的写法,就会发现很有意思的问题。factorial_A() 的自身调用属于表达式的一部分,这意味着自身调用不是函数的最后一步,而是拿到自身调用的结果后,需要再做一次乘法运算;factorial_B() 的自身调用则是函数的最后一步。像 factorial_B() 函数这样,当自身调用是整个函数体中最后执行的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归(Tail Recursion)。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。分别使用 factorial_A() 和 factorial_B() 计算5的阶乘,下图所示的计算过程,清晰展示了尾递归的优势:不用花费大量的栈空间来保存上次递归中的参数、局部变量等,这是因为上次递归操作结束后,已经将之前的数据计算出来,传递给当前的递归函数,这样上次递归中的局部变量和参数等就会被删除,释放空间,从而不会造成栈溢出。factorial_A(5)5 * factorial_A(4)5 * 4 * factorial_A(3)5 * 4 * 3 * factorial_A(2)5 * 4 * 3 * 2 * factorial_A(1)5 * 4 * 3 * 2 * 1 * factorial_A(0)5 * 4 * 3 * 2 * 15 * 4 * 3 * 25 * 4 * 65 * 24120factorial_B(5, k=1)factorial_B(4, k=5)factorial_B(3, k=20)factorial_B(2, k=60)factorial_B(1, k=120)factorial_B(0, k=120)120尾递归虽然有低耗高效的优势,但这一类递归一般都可转化为循环语句。4. 单向递归前文中两个递归函数,不管是阶乘还是斐波那契数列,递归总是向着递归出口方向进行,没有分支,没有反复,这样的递归,我们称之为单向递归。在文件递归遍历等应用场合,搜索完一个文件夹,通常要返回至父级目录,继续搜索其他兄弟文件夹,这个过程就不是单向的,而是有分叉的、带回溯的。通常复杂递归都不是单向的,算法设计起来就比较困难。import osdef ergodic(folder): for root, dirs, files in os.walk(folder): for dir_name in dirs: print(os.path.join(root, dir_name)) for file_name in files: print(os.path.join(root, file_name))上面是借助于 os 模块的 walk() 实现的基于循环的文件遍历方法。虽然是循环结构,如果不熟悉 walk() 的话,这个函数看起来还是很不直观。我更喜欢下面的递归遍历方法。import osdef ergodic(folder): for item in os.listdir(folder): obj = os.path.join(folder, item) print(obj) if os.path.isdir(obj): ergodic(obj)5. 深度优先与广度优先遍历文件通常有两种策略:深度优先搜索 DFS(depth-first search) 和广度优先搜索BFS(breadth-first search) 。顾名思义,深度优先就是优先处理本级文件夹中的子文件夹,递归向纵深发展;广度优先就是优先处理本级文件夹中的文件,递归向水平方向发展。import osdef ergodic_DFS(folder): """基于深度优先的文件遍历""" dirs, files = list(), list() for item in os.listdir(folder): if os.path.isdir(os.path.join(folder, item)): dirs.append(item) else: files.append(item) for dir_name in dirs: ergodic(os.path.join(folder, dir_name)) for file_name in files print(os.path.join(folder, file_name))def ergodic_BFS(folder): """基于广度优先的文件遍历""" dirs, files = list(), list() for item in os.listdir(folder): if os.path.isdir(os.path.join(folder, item)): dirs.append(item) else: files.append(item) for file_name in files print(os.path.join(folder, file_name)) for dir_name in dirs: ergodic(os.path.join(folder, dir_name)) 黑马程序员视频库网址:yun.itheima.(海量热门编程视频、资料免费学习) 学习路线图、学习大纲、各阶段知识点、资料网盘免费领取+QQ 3285264708 / 3549664195 . .jz.- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python 基础教程 入门教程 递归 算法
咨信网温馨提示:
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【二***】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【二***】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。
关于本文