目录 :算法
1、递归的简介编程
2、递归的经典应用数据结构
2.1 递归求阶乘函数
2.2 递归推斐波那契数列spa
2.3 二分法找有序列表指定值设计
2.4 递归解汉诺塔code
前言:对象
当咱们碰到诸如须要求阶乘或斐波那契数列的问题时,使用普通的循环每每比较麻烦,但若是咱们使用递归时,会简单许多,起到事半功倍的效果。这篇文章主要和你们分享一些和递归有关的经典案例,结合一些资料谈一下我的的理解,也借此加深本身对递归的理解和掌握一些递归基础的用法。blog
程序调用自身的编程技巧称为递归( recursion)。
递归作为一种算法在程序设计语言中普遍应用。 一个过程或函数在其定义或说明中有直接或
间接调用自身的一种方法,它一般把一个大型复杂的问题层层转化为一个与原问题类似的规模较小的问题
来求解,递归策略只需少许的程序就可描述出解题过程所须要的屡次重复计算,大大地减小了程序的代码量。
递归的能力在于用有限的语句来定义对象的无限集合。通常来讲,递归须要有边界条件、递归前进
段和递归返回段。当边界条件不知足时,递归前进;当边界条件知足时,递归返回。
递归就是在函数内部调用本身的函数被称之为递归。
(资料来源于知乎问答:https://www.zhihu.com/question/20507130)递归
一、咱们使用的词典,自己就是递归,为了解释一个词,须要使用更多的词。当你查一个词,发现这个词的解释中某个词仍然不懂,因而你开始查这第二个词,惋惜,第二个词里仍然有不懂的词,因而查第三个词,这样查下去,直到有一个词的解释是你彻底能看懂的,那么递归走到了尽头,而后你开始后退,逐个明白以前查过的每个词,最终,你明白了最开始那个词的意思。
二、一个小朋友坐在第10排,他的做业本被小组长扔到了第1排,小朋友要拿回他的做业本,能够怎么办?他能够拍拍第9排小朋友,说:“帮我拿第1排的本子”,而第9排的小朋友能够拍拍第8排小朋友,说:“帮我拿第1排的本子”...如此下去,消息终于传到了第1排小朋友那里,因而他把本子递给第2排,第2排又递给第3排...终于,本子到手啦!这就是递归,拍拍小朋友的背能够类比函数调用,而小朋友们都记得要传消息、送本子,是由于他们有记忆力,这能够类比栈。
三、 一个洋葱是一个带着一层洋葱皮的洋葱。
还有这个高赞的回答,图片十分形象(图片转自:https://www.zhihu.com/question/20507130/answer/114197404):
我想到一个比较接近咱们生活的例子,和那个传本子的例子相似,好比你喜欢一个女孩,你想告诉她,但你和她座位隔得很远,你写好了纸条,想同窗传过去,因而,你把纸条传给你前面的同窗,而后同窗又向前传,直到传到你喜欢的那个女孩手里,可是女孩已经有喜欢的人了,因而,她也写了一个纸条让原来的同窗再传回来给你,那么同窗之间打招呼传纸条的行为就能够看做是函数调用,你是最初调用的函数,那个你喜欢的女孩就是最终的目的地,纸条上的信息就是初始值和最终答案。
# -*- coding:utf-8-*- # 将 10不断除以2,直至商为0,输出这个过程当中每次获得的商的值。 def recursion(n): v = n//2 # 地板除,保留整数 print(v) # 每次求商,输出商的值 if v==0: ''' 当商为0时,中止,返回Done''' return 'Done' v = recursion(v) # 递归调用,函数内本身调用本身 recursion(10) # 函数调用
输出结果:
5
2
1
0
经过以上的介绍,咱们大体能够总结出递归的如下几个特色:
1、必须有一个明确的结束条件 2、每次进入更深一层递归时,问题规模(计算量)相比上次递归都应有所减小 三、递归效率不高,递归层次过多会致使栈溢出(在计算机中,函数调用是经过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。因为栈的大小不是无限的,因此,递归调用的次数过多,会致使栈溢出)
关于递归还有两个名词,能够归纳递归实现的过程
递推:像上边递归实现所拆解,递归每一次都是基于上一次进行下一次的执行,这叫递推
回溯:则是在遇到终止条件,则从最后往回返一级一级的把值返回来,这叫回溯
实例以下:
# 1!+2!+3!+4!+5!+...+n! def factorial(n): ''' n表示要求的数的阶乘 ''' if n==1: return n # 阶乘为1的时候,结果为1,返回结果并退出 n = n*factorial(n-1) # n! = n*(n-1)! return n # 返回结果并退出 res = factorial(5) #调用函数,并将返回的结果赋给res print(res) # 打印结果
实例以下:
# 1,1,2,3,5,8,13,21,34,55,试判断数列第十五个数是哪一个? def fabonacci(n): ''' n为斐波那契数列 ''' if n <= 2: ''' 数列前两个数都是1 ''' v = 1 return v # 返回结果,并结束函数 v = fabonacci(n-1)+fabonacci(n-2) # 由数据的规律可知,第三个数的结果都是前两个数之和,因此进行递归叠加 return v # 返回结果,并结束函数 print(fabonacci(15)) # 610 调用函数并打印结果
实例以下:
data = [1,3,6,13,56,123,345,1024,3223,6688] def dichotomy(min,max,d,n): ''' min表示有序列表头部索引 max表示有序列表尾部索引 d表示有序列表 n表示须要寻找的元素 ''' mid = (min+max)//2 if mid==0: return 'None' elif d[mid]<n: print('向右侧找!') return dichotomy(mid,max,d,n) elif d[mid]>n: print('向左侧找!') return dichotomy(min,mid,d,n) else: print('找到了%s'%d[mid]) return res = dichotomy(0,len(data),data,222) print(res)
未完待续。。。