day5-python之递归函数

1、初识递归

一、递归的定义

在一个函数里再调用这个函数自己,这种魔性的使用函数的方式就叫作递归。python

二、递归的深度

递归函数若是不受到外力的阻止会一直执行下去。每一次函数调用都会产生一个属于它本身的名称空间,若是一直调用下去,会形成名称空间占用太多内存。因而python为了杜绝相似内存溢出现象,强制将递归层数控制在了998。算法

def func():
    print(1)
    func()
func()   # 递归最大深度为:998

由此能够看出,未报错以前能看到的最大数字就是997。997是python为了程序的内存优化所设定的一个默认值,能够经过一些手段修改:函数

# 修改递归的最大深度(尽可能不要改)
import sys
sys.setrecursionlimit(1000000)   # 3221
def foo(n):
    print(n)
    n += 1
    foo(n)
foo(1)

能够经过这种方式来修改递归的最大深度,刚刚将python容许的递归深度设置为了10W,实际能够达到的深度取决于计算机的性能。不推荐修改这个默认的递归深度,若是用997层递归都没能解决的问题,要么不适合递归解决,要么代码写的太烂。
江湖流传这样一句话:人理解循环,神理解递归。
sys模块:包含全部和python相关的设置和方法。
递归就是本身调用本身。
递归须要有一个中止条件,若是没有中止条件就会报错。性能

2、再谈递归

例1:阶乘

6!优化

65432*1code

def fn(n):
    if n == 1:return 1
    return n*fn(n-1)
print(fn(6))

执行过程:
def fn(6):
return 6*fn(5)blog

def fn(5):
    return 5*fn(4)

def fn(4):
    return 4*fn(3)

def fn(3):
    return 3*fn(2)

def fn(2):
    return 2*fn(1)

def fn(1):
    return 1

例2:猜小明年龄

小明是新来的同窗,丽丽问他多少岁了。排序

他说:我不告诉你,可是我比滔滔大两岁。递归

滔滔说:我也不告诉你,我比晓晓大两岁内存

晓晓说:我也不告诉你,我比小星大两岁

小星也没有告诉他说:我比小华大两岁

最后小华说,我告诉你,我今年18岁了

知道小华的,就会知道小星的,知道小星的就会知道晓晓的,以此类推,就会知道小明的年龄。这个过程接近递归思想。

  • 小华 18+2
  • 小星 20+2
  • 晓晓 22+2
  • 滔滔 24+2
  • 小明 26+2

用序号表示:

age(5) = age(4)+2
age(4) = age(3) + 2 
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18

写成代码:

def age(n):
    if n == 1:
        return 18
    else:
        return age(n - 1) + 2
ret = age(6)
print(ret)

例3: 一个数除2,知道不能整除

def cal(num):
    if  num%2==0:     #先判断能不能整除
        num=num//2
        return cal(num)
    else:
        return num
print(cal(8))

例4:一个数能够整除2,就整除。不能整除就*3+1

def func(num):
    print(num)
    if num==1:
        return
    if num%2==0:
        num=num//2
    else:
        num=num*3+1
    func(num)
func(5)

3、二分查找算法

# 人类的算法(灵活)

9999=99(100-1)=9900-99=9801

# 计算机的算法(死板)
99*99

计算一些比较复杂的问题,所采用的在空间上(内存里)或者时间上(执行时间)更有优点的方法

# 排序 500W个数:快速排序、堆排序、冒泡排序

# 查找

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

# 简单版二分法
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def cal(l,num=66):
    length = len(l)
    mid = length//2
    if num > l[mid]:
        l = l[mid+1:]
        cal(l,num)
    elif num < l[mid]:
        l = l[:mid]
        cal(l, num)
    else:
        print('找到了',l[mid],mid)
cal(l,66)


# 升级版二分法
def cal(l,num,start=0,end=None):
    # if end is None:end = len(l)-1
    end = len(l)-1 if end is None else end
    if start <= end:
        mid = (end - start)//2 + start
        if l[mid] > num :
            return cal(l, num, start, mid-1)
        elif l[mid] < num:      # 13  24
            return cal(l,num,mid+1,end)
        else:
            return mid
    else:
        return None
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
print(cal(l,56))
相关文章
相关标签/搜索