python递归函数二分法_Python基础之递归函数与二分法

一、递归函数

定义:

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

我们来举个例子吧,比如:有个人问“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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值