alex博客中递归的博文     我之前确实没讲明白递归这个东西

  • 递归就是在函数的运行过程中调用自己。
  • 但递归不断调用自己是有限度的,默认限度为1000。函数不断被压进栈,当超过递归限度时会造成栈溢出,程序会崩掉。
import sys

print(sys.getrecursionlimit())
sys.setrecursionlimit(1500) #修改递归最大次数,默认为1000 def recursion(n):
print(n)
recursion(n+1) recursion(1)
  • 递归进行,再次调用函数本身时,并没有跳出上一层函数,所以,在最后全部调用完输出时,会从里到外再运行一遍。
>>> def calc(n):
... v = int(n/2)
... print(v)
... if v == 0:
... return 'Done'
... calc(v)
... print(v)
...
>>> calc(10)
5
2
1
0
1
2
5
  • 递归特性总结:
    1. 如果不加控制,递归会无限制的调用。因此递归需要一个结束控制。
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
    3. 递归执行效率不高,递归层次过多会导致栈溢出。
  • 递归的作用:有些问题只能用递归来解决,如:求斐波那契数列、汉诺塔问题、多级评论树、二分查找、求阶乘等。
  1. 求阶乘:n! = n*(n-1)*(n-2)*...*3*2*1
def factorial(n):

    if n==1:
return 1
return n * factorial(n-1) print(factorial(10))

2.二分查找

我们首先引入这样一个问题:如果规定某一科目成绩分数范围:[0,100],现在小明知道自己的成绩,他让你猜他的成绩,如果猜的高了或者低了都会告诉你,用最少的次数猜出他的成绩,你会如何设定方案?(排除运气成分和你对小明平时成绩的了解程度)

①最笨的方法当然就是从0开始猜,一直猜到100分,考虑这样来猜的最少次数:1(运气嘎嘎好),100(运气嘎嘎背);

②其实在我们根本不知道对方水平的条件下,我们每一次的猜测都想尽量将不需要猜的部分去除掉,而又对小明不了解,不知道其水平到底如何,那么我们考虑将分数均分,将分数区间一分为2,我们第一次猜的分数将会是50,当回答是低了的时候,我们将其分数区域从【0,100】确定到【51,100】;当回答高了的时候,我们将分数区域确定到【0,49】。这样一下子就减少了多余的50次猜想(从0数到49)(或者是从51到100)。

③那么我们假设当猜完50分之后答案是低了,那么我们需要在【51,100】分的区间内继续猜小明的分数,同理,我们继续折半,第二次我们将猜75分,当回答是低了的时候,我们将其分数区域从【51,100】确定到【76,100】;当回答高了的时候,我们将分数区域确定到【51,74】。这样一下子就减少了多余的猜想(从51数到74)(或者是从76到100)。

④就此继续下去,直到回复是正确为止,这样考虑显然是最优的。

        转换成代码

在一个已排序的数组data_set中,使用二分查找n,假如这个数组的范围是[low...high],我们要的n就在这个范围里。查找的方法是拿low到high的正中间的值,我们假设是mid,来跟n相比,如果mid>n,说明我们要查找的n在前数组data_set的前半部,否则就在后半部。无论是在前半部还是后半部,将那部分再次折半查找,重复这个过程,知道查找到n值所在的地方。

# data_set = [1,3,4,6,7,8,9,10,11,13,14,16,18,19,21]
data_set = list(range(101)) def b_search(n, low, high, d):
mid = int((low + high) / 2) # 找到列表中间的值
if low == high:
print("not find")
return
if d[mid] > n: # 列表中间值>n, 代数要找的数据在左边
print("go left:", low, high, d[mid])
b_search(n, low, mid, d) # 去左边找
elif d[mid] < n: # 代数要找的数据在左边
print("go right:", low, high, d[mid])
b_search(n, mid + 1, high, d) # 去右边找
else:
print("find it ", d[mid]) b_search(188, 0, len(data_set), data_set)
  • 尾递归:可以实现递归过程中不产生多层栈,不会溢出。

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归进行时,栈会被覆盖而不是创建,以此来保证尾递归的不断运行。

def cal(n):
print(n)
return cal(n+1) #返回值不属于表达式的一部分 cal(1)

Python全栈之路----递归的更多相关文章

  1. Python全栈之路----目录

    Module1 Python基本语法 Python全栈之路----编程基本情况介绍 Python全栈之路----常用数据类型--集合 Module2 数据类型.字符编码.文件操作 Python全栈之路 ...

  2. python 全栈之路

    目录 Python 全栈之路 一. Python 1. Python基础知识部分 2. Python -函数 3. Python - 模块 4. Python - 面对对象 5. Python - 文 ...

  3. Python全栈之路目录结构

    基础 1.Python全栈之路-----基础篇 2.Python全栈之路---运算符与基本的数据结构 3.Python全栈之路3--set集合--三元运算--深浅拷贝--初识函数 4.Python全栈 ...

  4. Python全栈之路----常用模块----hashlib加密模块

    加密算法介绍 HASH       Python全栈之路----hash函数 Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列 ...

  5. Python全栈之路----函数----返回值

    函数外部的代码想要获取函数的执行结果,就可以在函数里用return语句,把结果返回. def stu_register(name,age,course='PY',country='CN'): prin ...

  6. Python全栈之路----常用模块----shutil模块

    高级的 文件.文件包.压缩包 处理模块   参考Python之路[第四篇]:模块     #src是原文件名,fdst是新文件名 shutil.copyfileobj(fsrc, fdst[, len ...

  7. Python全栈之路4--内置函数--文件操作

    上节重点回顾: 判断对象是否属于某个类,例如: 列表中有个数字,但是循环列表判断长度,用len会报错;因为int不支持len,所以要先判断属于某个类,然后再进行if判断. # isinstance(对 ...

  8. Python全栈之路-Day33

    1 time模块 #!/usr/bin/env python # __Author__: "wanyongzhen" # Date: 2017/4/7 import time # ...

  9. Python全栈之路----常用模块----软件开发目录规范

    目录基本内容 log  #日志目录 conf  #配置目录 core/luffycity  #程序核心代码目录  #luffycity 是项目名,建议用小写 libs/modules  #内置模块 d ...

随机推荐

  1. poj1985和poj1849(树的直径)

    题目传送门:poj1985 树是连通无环图,树上任意两点之间的路径是唯一的.定义树上任 意两点u, v的距离为u到v路径上边权的和.树的直径MN为树上最长路 径,即点M和N是树上距离最远的两个点. 题 ...

  2. Pandas之索引

    Pandas的标签处理需要分成多种情况来处理,Series和DataFrame根据标签索引数据的操作方法是不同的,单列索引和双列索引的操作方法也是不同的. 单列索引 In [2]: import pa ...

  3. android to hide the keybord

    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hi ...

  4. JAVA中的值传递和引用传递问题

    这是个老生常谈的问题了,引起过无数争论,但可以说一直没有一个令人满意的回答. 有人总结过: 对象是按引用传递的 Java 应用程序有且仅有的一种参数传递机制,即按值传递 按值传递意味着当将一个参数传递 ...

  5. linux内核升级5.0

    升级内核$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org$ rpm -Uvh http://www.elrepo.org/elr ...

  6. 『TensotFlow』转置卷积

    网上解释 作者:张萌链接:https://www.zhihu.com/question/43609045/answer/120266511来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  7. javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names

    问题:在使用 org.apache.http.*下的 CloseableHttpClient 发送https请求时报了以上错误 解决方案一:使用java.net.HttpURLConnection i ...

  8. vscode 快捷键

    ctrl+/   单行注释:// 若要多行注释://,先选中这些要注释的行,再按ctrl+/ shift+Alt+A 多行注释 撤销刚才的操作:Ctrl+Z 恢复刚才的操作:Ctrl+Shift+Z ...

  9. configure、make 和 make install 的区别

    Linux编译安装中configure.make和make install各自的作用 ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GC ...

  10. liunx文件操作 文件压缩

    文件备份和压缩命令 在Linux中,常用的文件压缩工具有gzip,bzip2,zip. 'bzip2'是最理想的压缩工具,它提供了最大限度的压缩. 'zip'兼容好,windows也支持. bzip2 ...