• 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

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

  • 相关阅读:
    HihoCoder#1513 : 小Hi的烦恼(五维数点 bitset 分块)
    cf914F. Substrings in a String(bitset 字符串匹配)
    BZOJ4503: 两个串(bitset字符串匹配)
    HDU5972Regular Number(ShiftAnd算法 bitset)
    BZOJ1563: [NOI2009]诗人小G(决策单调性 前缀和 dp)
    cf868F. Yet Another Minimization Problem(决策单调性 分治dp)
    BZOJ4709: [Jsoi2011]柠檬(决策单调性)
    cf633F. The Chocolate Spree(树形dp)
    BZOJ1044: [HAOI2008]木棍分割(dp 单调队列)
    2、RenderScript的计算(2013.05.07)
  • 原文地址:https://www.cnblogs.com/Michael--chen/p/6714395.html
Copyright © 2020-2023  润新知