• 递归函数


    1、什么是递归?

    从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?「从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?『从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……』」

    2、函数的嵌套调用

    函数内部是可以调用其他函数的,这种调用就叫函数的嵌套调用。

    而递归就是函数在其内部直接或间接调用自己。

    3、Python中使用递归的注意事项

    1. 必须有明确的退出条件

    2. 每次进入更深一层递归时,问题规模比上次递归都应有所减少

    3. 递归效率不高,递归层数过多会导致栈溢出

      在计算机中,函数调用是通过栈(stack)这种数据结构实现的。每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,就会导致栈溢出。)

      查看Python中递归限制:

    >>> import sys
    >>> sys.getrecursionlimit()
    1000

    4、常见应用

      4.1 剥皮

    def f(x):
        ret = []
        for b in x:
            if isinstance(b, list):
                for a in f(b):
                    ret.append(a)
            else:
                ret.append(b)
        return ret
    
    list2 = [11, 22, [33, 44], [55, [66, 77]], [88, [99, [100, [200, [300]]]]]]
    ret = f(list2)
    print(ret)     #[11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 200, 300]

      4.2 二分法

    # 二分查找算法:必须处理有序的列表
    
    ################# 二分法基础版
    l = [2,3,5,6,8,9,15,18,23,26,33,35,38,59,67,89,90,99]
    def find(l,aim):
        mid_index = int(len(l) // 2)
        if l:
            if l[mid_index] < aim:
                new_l = l[mid_index+1 :]
                find(new_l,aim)
            elif l[mid_index] > aim:
                new_l = l[:mid_index]
                find(new_l, aim)
            else:
                print('找到了',mid_index,l[mid_index])
        else:
            print('找不到')
    find(l,36)  # 找不到
    find(l,18)  # 找到了 2 18     此处的mid_index不对
    
    ----------------------------------------------------------------------------------------
    
    ################ 二分法升级版
    def find(l,aim,start = 0,end = None):
        end = len(l) if end is None else end  #参数end问题
        mid_index = (end - start)// 2 + start  # 计算中间值
        if start <= end:               # 针对找不到的值
            if l[mid_index] < aim:
                return find(l,aim,start=mid_index+1,end=end)
            elif l[mid_index] > aim:
                return find(l, aim, start=start, end=mid_index-1)
            else:
                return mid_index
        else:
            return '找不到该值'
    
    l = [2,3,5,6,8,9,15,18,23,26,33,35,38,59,67,89,90,99]
    ret = find(l,18)
    print('要找的值对应的下标是:',ret)     # 要找的值对应的下标是: 7

      4.3 递归函数实现三级菜单

    menu = {
        '北京':{'海淀':{'五道口':{'soho':{},'网易':{},'google':{}},
                       '中关村':{'爱奇艺':{},'汽车之家':'','youku':{}},
                       '上地':{'百度':{}}
                      },
               '昌平':{'沙河':{'老男孩':'','北航':{}},
                       '天通苑':{},
                       '回龙观':{}
                      },
               '朝阳':{},
               '东城':{}
              },
        '上海':{'闵行':{'人民广场':{'炸鸡店':{}}
                      },
                '闸北':{'火车站':{'携程':{}}
                      },
                '浦东':{}
              },
        '山东':{}
    }
    
    l = [menu]
    # print(l[-1])    #l[-1]其实就是字典menu
    while l:
        for key in l[-1]:   # l[-1]:列表最后一个元素,也就是最新的(可能是新添加的)
            print(key)
        k = input('input>>>').strip()
    
        if k in l[-1].keys() and l[-1][k]:
            l.append(l[-1][k])
        elif k == 'b':
            l.pop()        #pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
        elif k == 'q':
            break
        elif k not in l[-1].keys():
            print('该地点没找到,请重新从下边列表中选择:')
            print('-' * 20)
        elif not (l[-1][k]):
            print('该地点下辖是空值,请重新从下边列表中选择:')
            print('-'*20)
    
    # 函数实现
        # def threeLM(dic):
        #     while 1:
        #         for k in dic:
        #             print(k)
        #         # print(dic.keys())   #dict_keys(['北京', '上海', '山东'])
        #         key = input('imput>>>').strip()
        #         # print(dic[key])   #{'海淀': {'五道口': {'soho': {}, '网易': {}, 'google': {}}, '中关村': {'爱奇艺': {}, '汽车之家': '', 'youku': {}}, '上地': {'百度': {}}}, '昌平': {'沙河': {'老男孩': '', '北航': {}}, '天通苑': {}, '回龙观': {}}, '朝阳': {}, '东城': {}}
        #         if key == 'b' or key == 'q':
        #             return key
        #         elif key in dic.keys() and dic[key]:
        #             ret = threeLM(dic[key])
        #             if ret == 'q':
        #                 return 'q'
        #         elif (not dic.get(key)) or (not dic[key]):
        #             continue
        #
        # threeLM(menu)
    
    #运行结果:
    
    北京
    上海
    山东
    input>>>北京
    海淀
    昌平
    朝阳
    东城
    input>>>昌平
    沙河
    天通苑
    回龙观
    input>>>回龙观
    该地点下辖是空值,请重新从下边列表中选择:
    ------------------------------
    沙河
    天通苑
    回龙观
    input>>>沙河
    老男孩
    北航
    input>>>老男孩
    该地点下辖是空值,请重新从下边列表中选择:
    ------------------------------
    老男孩
    北航
    input>>>b
    沙河
    天通苑
    回龙观
    input>>>b
    海淀
    昌平
    朝阳
    东城
    input>>>b
    北京
    上海
    山东
  • 相关阅读:
    shell 冒泡算法 解决数组排序问题
    react(二)
    react(一)
    mybatis-plus:3
    lambda
    配置中心(nacos)-控制台使用
    nacos作为配置中心的简单项目配置
    nacos作为注册中心的简单项目配置
    Vue初步学习
    nacos单例模式简单搭建
  • 原文地址:https://www.cnblogs.com/timetellu/p/10684677.html
Copyright © 2020-2023  润新知