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. MATLAB raw格式转为bmp格式

    今天是第一天写博客,哈哈哈!把完成的数字图像作业放上来和大家一起分享一下! 如果有什么问题,希望大家和我多多交流 1518234852@qq.com width=512; height=512; im ...

  2. linux基础之grep

    grep: Global search REgular expression and Print out the line 作用: 文本搜索工具,根据用户指定的模式对目标文本逐行进行匹配检查,打印匹配 ...

  3. Learning-Python【19】:Python常用模块(2)—— os、sys、shutil

    os模块:与操作系统相关的模块 import os # 获取当前的工作目录 print(os.getcwd()) # 切换工作目录 os.chdir(r'E:\Python\test') print( ...

  4. Linux常用命令——文件搜索命令

    Linux常用命令——文件搜索命令 Linux  以#号开头的内容都是内容描述或配置项 find 描述:文件搜索 语法:find [搜索范围] [范围条件] . 当前目录 示例:[root@local ...

  5. Java自带RPC实现,RMI框架入门

    Java自带RPC实现,RMI框架入门 首先RMI(Remote Method Invocation)是Java特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种 ...

  6. Linux wc -l 统计文件行数存在的问题

    1.使用这种方式效率较低,而且不注意可能出现错误 find  . -name "*.pc" |xargs wc -l 直接查看 total 不是正确的值. 原因: 这种方式存在一个 ...

  7. 学习笔记69—金蝶财务软件安装教程(KIS12.3,win10)

    ****************************************************** 如有谬误,请联系指正.转载请注明出处. 联系方式: e-mail: heyi9069@gm ...

  8. SSH 远程登陆

    2019-03-10 20:41:39 一.什么是SSH 简单说,SSH是一种网络协议,用于计算机之间的加密登录. 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登 ...

  9. poj3613

    注意最短路转移的单位元是对角线为0,其它为INF. #include <iostream> #include <cstdio> #include <cmath> # ...

  10. POJ-3233 Matrix Power Series 矩阵A^1+A^2+A^3...求和转化

    S(k)=A^1+A^2...+A^k. 保利求解就超时了,我们考虑一下当k为偶数的情况,A^1+A^2+A^3+A^4...+A^k,取其中前一半A^1+A^2...A^k/2,后一半提取公共矩阵A ...