day5-python之递归与二分法

Posted xiechao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)

  

  

 

以上是关于day5-python之递归与二分法的主要内容,如果未能解决你的问题,请参考以下文章

what' the python之递归函数与二分算法

递归-之二分查找与选择排序算法

计算机算法设计与分析之递归与分治策略——二分搜索技术

day5-python之面向过程编程

二分查找算法(递归与非递归两种方式)

递归函数之二分查找