zoukankan      html  css  js  c++  java
  • day5-python之递归与二分法

    一、递归的定义

    递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用

    二、递归分为两个阶段:递推,回溯

    age(5) = age(4) + 2
    age(4) = age(3) + 2
    age(3) = age(2) + 2
    age(2) = age(1) + 2
    age(1) = 18
    
    age(n)=age(n-1)+2 #n>1
    age(1)=18 #n=1
    
    ##########################3
    def age(n):
        if n == 1:
            return 18
        return age(n - 1) + 2
    
    
    print(age(5))

    三、python中的递归效率低且没有尾递归优化

    #python中的递归
    python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
    但是python又没有尾递归,且对递归层级做了限制
    
    #总结递归的使用:
    1. 必须有一个明确的结束条件
    
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    
    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出) 

    四、可以修改递归最大深度

    import sys
    sys.getrecursionlimit()
    sys.setrecursionlimit(2000)
    n=1
    def test():
        global n
        print(n)
        n+=1
        test()
    
    test()
    
    虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归

    五:递归应用

    应用:把列表所有的内容取出来
    
    l = [1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15, [16, [17, ]], 19]]]]]]]
    
    
    def search(l):
        for item in l:
            if type(item) is list:
                search(item)
            else:
                print(item)
    
    
    search(l)

    六、二分法

    想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

    1、找某个数字在不在列表里边

    l = [1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102, 130, 240]
    
    +++++++++++++++++++++++++++++++++++
    a=len(l) //2
    print(a)#6
    print(len(l))#13
    print(l[6:]) #[44, 47, 56, 99, 102, 130, 240]
    print(l[:6]) #[1, 2, 5, 7, 10, 31]
    +++++++++++++++++++++++++++++++++++
    
    
    
    def binary_search(l, num):
        print(l)  # [10, 31]
        if len(l) > 1:   #如果列表的长度大于一,就执行下面的递归操作
            mid_index = len(l) // 2  # 把列表切分成两半,拿到中间值的索引 44的索引为6
            if num > l[mid_index]:  # 用户要找的值跟中间那个值比较,如果大于中间值,那么这个值在列表右边
                l = l[mid_index:]  # l=[31],切分,去右边找值
                binary_search(l, num)  # 递归一次,规模减少一半
            elif num < l[mid_index]:  # 如果是小于中间值的话,那么这个值就在列表的左边
                l = l[:mid_index]  # 切分
                binary_search(l, num)
            else:
                print('find it')
        else:
            if l[0] == num:##如果列表中就存在一个值,如果这个值就是我要找的那个值,就直接打印
                print('find it')
            else:
                print('not exist')
            return
    
    
    binary_search(l, 32)
    

    2、找某个数字在不在列表里边优化版

    l = [1, 2, 5, 7, 10, 31, 44, 47, 56, 99, 102, 130, 240]
    
    
    def binary_search(l, num):
        print(l)
        if len(l) == 1:
            if l[0] == num:
                print('find it')
            else:
                print('not exists')
            return
        mid_index = len(l) // 2
        mid_value = l[mid_index]
        if num == mid_value:
            print('find it')
            return
        if num > mid_value:
            l = l[mid_index:]
        if num < mid_value:
            l = l[:mid_index]
        binary_search(l, num)
    
    
    binary_search(l, 32)
    

      

      

  • 相关阅读:
    手把手教您玩转信用卡 如何“以卡养卡”合法“套现”
    267家已获第三方许可机构名单查询
    C#生成图片验证码
    File I/O
    文件上传代码
    集合框架
    接口
    多态
    封装
    jsp做成mvc模式的代码
  • 原文地址:https://www.cnblogs.com/xiechao621/p/8034976.html
Copyright © 2011-2022 走看看