• day5-python之递归函数


    一、初识递归

    1、递归的定义

    在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归。

    2、递归的深度

    递归函数如果不受到外力的阻止会一直执行下去。每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,会造成名称空间占用太多内存。于是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相关的设置和方法。
    递归就是自己调用自己。
    递归需要有一个停止条件,如果没有停止条件就会报错。

    二、再谈递归

    例1:阶乘

    6!

    65432*1

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

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

    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)
    

    三、二分查找算法

    # 人类的算法(灵活)

    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))
  • 相关阅读:
    [LeetCode] 16. 3Sum Closest 解题思路
    [LeetCode] 28. Implement strStr() 解题思路
    我所理解的 KMP(Knuth–Morris–Pratt) 算法
    [LeetCode] 86. Partition List 解题思路
    [LeetCode] 61. Rotate List 解题思路
    [LeetCode] 11. Container With Most Water My Submissions Question 解题思路
    如何强制卸载阿里云盾(安骑士)监控及屏蔽云盾IP检测&附带教程
    让Nginx支持pathinfo
    linux下解压rar文件
    Linux查看物理CPU个数、核数、逻辑CPU个数
  • 原文地址:https://www.cnblogs.com/gao-dong/p/9027274.html
Copyright © 2020-2023  润新知