一、递归函数

  定义:

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

  我们来举个例子吧,比如:有个人问“egon”年龄,他说比“小大”大5岁,“小大”又说比“小保”大5岁,“小保”又说

比“小健”大5岁,最后,“小健”又问我,我又比“小健”小5岁。已知我今年20岁,求“egon”今年多少岁?

  分析:看到这个题,我们首先可以发现这中间有一个规律,就是问的这几个人彼此间年龄的差距正好是5岁,既然,

有了这个规律,就好办了。在看一共问了几个人,就可以得出“egon”的年龄了。

  用代码表示如下:

def age(n): #形参n表示问的人数
if n == 1 : #当"n==1"时,即返回我的年龄20
return 20
else:
return age(n-1)+5 #每问一个人,加5岁
print(age(5)) #打印"egon"的年龄,已知他问了4个人,"小大"、"小保"、"小健"、"我"加上“egon”自己共5个人
-----------------输出结果-------------------
40 #得出"egon"的年龄

  下面我们就用图来看看具体的流程吧!

  递归函数的特点:

    1、调用自身函数;

    2、有一个明显的结束条件,问题规模相比上次递归有所减少。

  递归函数的优点:

    定义简单,思维逻辑简单。理论上,所有的递归函数都可以写成循环的方式,但是循环的逻辑不如递归清晰。

  递归函数的缺点:

    递归的效率不高,递归层次过多会导致栈溢出,默认的栈大概是1000层。

  注意:

  使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个

函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数

过多,会导致栈溢出。

  二、二分法

  二分法是一种快速查找的方法,复杂度低,逻辑简单易懂,总的来说就是不断的除以2除以2...不断缩小范围,快速

查找想要的元素。

  下面我们还是来举例说明吧!

  已知data是一个按升序排列的列表,我们要查看一个元素是否在列表中。

  data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]

  代码如下:

#定义递归函数阶段
def search(num,data): #用递归函数使用二分法
da_index = int(len(data)/2)
da_values = data[da_index]
if len(data) > 1: #要data的长度大于1时,防止最后只剩一个元素的特殊情况
if da_values > num : #当中间的值大于num的时候
data = data[:da_index] #我们就要取列表中间往左边所有值的范围
return search(num,data) #返回切后的列表给函数,继续查找元素
elif da_values < num : #当中间的值小于num的时候
data = data[da_index:] #我们就要取列表中间往右边所有值的范围
return search(num,data) #返回切后的列表给函数,继续查找元素
else: #不大不小就正好是要找的元素
print("已找到%s,在data中"%num)
return
else:#因为是二分查找,特别是列表两头的元素,就会容易出现之下一个的情况
if data[0] == num : #只剩下一个元素的时候,判断是否为要查的元素
print("已找到%s,在data中"%num)
else: #不是就走下面的代码
print("Sorry,data中没有这个元素:%s"%num)
#调用函数阶段
search(18,data) #调用函数,查找18是否在data中
search(1,data) #调用函数,查找1是否在data中,元素在列表最开头位置
search(35,data) #调用函数,查找35是否在data中,元素在列表最末尾位置
search(56,data) #调用函数,查找56是否在data中
-----------------------输出结果----------------------------
已找到18,在data中
已找到1,在data中
已找到35,在data中
Sorry,data中没有这个元素:56

  我们在来一个无序的元组,来查找一下里面是否有我们需要的元素在里面。好了,小二上菜:

  t = ("a","i","j","d","l","f","g","h","b","c","k","e")

  代码如下:

#定义递归函数阶段
def search(letter,t): #用递归函数使用二分法
t_index = int(len(t)/2) #加上int得到元组中间索引值的整数
if len(t) > 0: #元组的长度大于0时,走下面代码
if letter in t[t_index]: #当要查的元素和中间索引值的元素对应的时候,则判断找到
print("已找到 %s,在元组t中"%letter) #打印输出结果
return #结束函数
elif letter not in t[t_index:]: #当要查的元素没有在右边元组里的时候
t = t[:t_index] #重新定义选定的范围在中间索引值的左边的元组
return search(letter,t) #结束函数,返回得到结果,重新调用函数
elif letter not in t[:t_index]: #当要查的元素没有在左边元组里的时候
t = t[t_index:] #重新定义选定的范围在中间索引值的右边的元组
return search(letter,t) #结束函数,返回得到结果,重新调用函数
else: #当t长度为0的时候,说明里面没有值了,就说明要查的元素没在元组t中
print("Sorry, t 中没有这个元素:%s" % letter) #打印输出结果
#调用函数阶段
search("j",t) #调用函数,查找"j"是否在t中
search("a",t) #调用函数,查找"a"是否在t中,元素在最开头的位置
search("e",t) #调用函数,查找"e"是否在t中,元素在最末尾的位置
search("z",t) #调用函数,查找"z"是否在t中
-----------------------输出结果---------------------
已找到 j,在元组t中
已找到 a,在元组t中
已找到 e,在元组t中
Sorry, t 中没有这个元素:z

  注意:二分法查找非常快且非常常用,二分法查找的前提必须待查找的序列是一个有序的。

Python基础之递归函数与二分法的更多相关文章

  1. python基础之递归、二分法

    一 递归 1. 必须有一个明确的结束条件2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结 ...

  2. Python基础(递归函数)

    def age(n): if n == 1: return 18 else: return age(n - 1) + 2 ret=age(100) print(ret)#216 def test(nu ...

  3. python基础——匿名函数及递归函数

    python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x ...

  4. python基础——递归函数

    python基础——递归函数 递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用 ...

  5. python基础---递归函数真题解析

    方法一.有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中. 即: {'k ...

  6. python基础篇(完整版)

    目录 计算机基础之编程和计算机组成 什么是编程语言 什么是编程 为什么要编程 编程语言的分类 机器语言(低级语言) 汇编语言 高级语言 计算机的五大组成 CPU(相当于人类的大脑) 多核CPU(多个大 ...

  7. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  8. Python基础教程【读书笔记】 - 2016/7/24

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第九波:第9章  魔法方法.属性和迭代器  在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.已 ...

  9. Python基础教程【读书笔记】 - 2016/6/26

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第一波:第6章  抽象 [总览] 介绍函数.参数parameter.作用于scope概念,以及递归概念. [6.1] 函 ...

随机推荐

  1. LOJ #6374「SDWC2018 Day1」网格

    模拟赛考过的题 当时太菜了现在也一样只拿到了$ 30$分 回来填个坑 LOJ #6374 题意 你要从$ (0,0)$走到$ (T_x,T_y)$,每次移动的坐标增量满足$ 0 \leq \Delta ...

  2. js原生事件

    js原生事件封装 // 事件处理对象 var EventUtil = { // 添加事件监听 add: function(element, type, callback){ if(element.ad ...

  3. jmeter (六) 登录 token获取

    有时候登录请求中会含有token字段,如下,此时就需要提取token 怎么提取token呢,其实很简单,通过正则表达式就可以了 1.添加http请求:获取登录页面,为“get”方式 2.在此http请 ...

  4. hibernate(一) 第一个hibernate工程

    序言 其实hibernate已经学过一遍,不过因为太糊弄,急于求成,导致现在需要重新来学习,通过亲自去敲每一行代码,来去理解每一个知识点. ---WH 一.什么是Hibernate? 轻量级JavaE ...

  5. python,关于这个里边的私有方法(private)、保护方法(protected)、公开方法(public)

    __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的. _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行 ...

  6. P3168 [CQOI2015]任务查询系统

    题目地址:P3168 [CQOI2015]任务查询系统 主席树的模板题 更模板的在这儿:P3834 [模板]可持久化线段树 1(主席树) 形象的说,P3834是"单点修改,区间查询" ...

  7. C/S 开发框架 ----- 广州本地

    C/S 开发框架 -----  广州本地: 1) 爱奇迪    http://www.iqidi.com       发现一个源码出售站   http://www.51aspx.com/code/co ...

  8. MySQL登录报错ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

    [root@pisphkdcbsql01 mysql3307]# /opt/mysql3307/bin/mysql -upisp -ppisp@ mysql: [Warning] Using a pa ...

  9. 移动硬盘和u盘的区别

    移动硬盘和U盘都属于便携性存储器,用于计算机之间的数据交换.但移动硬盘和U盘的区别还是非常大的,包括内部构造.容量以及整体外观上. 移动硬盘又分为机械移动硬盘和固态移动硬盘两种,主要区别在于内置的存储 ...

  10. struts2框架之类型转换(参考第二天学习笔记)

    类型转换 1. 什么是类型转换 刚才学习了封装请求参数,把表单数据封装到Action(模型)的属性中.表单中的数据都是String类型,但Action(模型)的属性不一定什么类型. 将来我们还需要数据 ...