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. POI使用记录

    POI CellType类型 CellType  类型  值 CELL_TYPE_NUMERIC  数值型  0 CELL_TYPE_STRING  字符串型 1 CELL_TYPE_FORMULA ...

  2. maven 执行testng.xml文件失败解决问题

    在pom.xml中配置了testng的依赖后,在surefire-plugin中又配置了suitexmlfiles指向testng.xml文件,但是使用mvn test运行时,没有运行testng.x ...

  3. [译]RabbitMQ教程C#版 - "Hello World"

    先决条件 本教程假定 RabbitMQ 已经安装,并运行在localhost标准端口(5672).如果你使用不同的主机.端口或证书,则需要调整连接设置. 从哪里获得帮助 如果您在阅读本教程时遇到困难, ...

  4. 在WPF中调用打开文件对话框

    // Create OpenFileDialog Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); ...

  5. _mount_vendor

    允许NPC售卖坐骑时进行预览

  6. Android 回退键监听

    回退键(back)监听:方法1:回调方法onBackPressed String LOG_TAG="TAG";  @Override    public void onBackPr ...

  7. ECharts注释

    <!DOCTYPE html> <head> <meta charset="utf-8"> <title>ECharts</t ...

  8. Bupt归队赛, gunfight

    只需要关心是否开枪,上个人和当前这个人的位置关系,转移可以前缀和优化 为了不重复,始终认为第一个就是1,最后答案乘以n #include<bits/stdc++.h> using name ...

  9. 在 .NET项目中使用 Redis(2018.10.16)

    1. 打开NuGet管理器搜索redis,安装:“StackExchange.Redis” 2. 配置 Web.config 文件 <connectionStrings> <add ...

  10. Hyperledger fabric-sdk-java Basics Tutorial(转)

    原文地址:Hyperledger fabric-sdk-java Basics Tutorial This quick tutorial is for all Java developers, who ...