重新认识递归

什么是递归?

  递归,就说函数在运行的过程中调用自己。

代码如下:

def recursion(n):
    print(n)
    recursion(n+1)
recursion(1)

出现的效果,就是这个函数在不断的调用自己,每次调用n+1相当于循环。

结果如下:

可是为何执行了900多次就出错了?还说超过了最大递归深度限制,为什么要限制?

通俗讲,每个函数在调用自己的时候,还未退出,占内存,多了会导致内存崩溃。

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

 递归的特点

   通过现象看本质,下面是用递归写的程序,让10不断除以2,直到0为止。

def cacl(n):
    print('--->', n)
    if int(n/2) > 0:
        cacl(int(n/2))
    else:
        print('---')
    print(n)

cacl(10)

运行结果:

 为何结果先打印10、5、2、1,然后又打印了1、2、5、10呢? 打印10、5、2、1可以理解,因为函数在一层一层的调用自己,但1、2、5、10是什么逻辑呢?因为当前函数在执行过程中又调用了自己一次,当前这次函数还没结束,程序就又进入了第2层函数调用,第2层还没结束就又进入了第3层,直到n/2>0不成立时才停止,此时问你,程序现在结束了吗?no,no,现在递归已经走到最里层,最里层的函数不需要继续递归了,会执行下方的else 判断。

 

打印的时1,然后最里层的函数就结束了。结束后会返回到之前调用它的位置,即上一层,上一层打印的时2,再就是5、10,即最外层函数,然后结束。

总结:

递归就是一层一层进去,还要一层一层出来。

 最后的总结:

  1. 必须有一个明确的结束条件,要不就会变成死循环,最后系统down。

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

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

 递归有什么用?

 求阶乘

   任何大于1的自然数n阶乘表示方法:

   n! = 1*2*3*4*....*n

   n! = n *(n-1)!

用递归代码来实现:

def fun(n):
    if n == 0:
        return 1
    return n * fun(n -1)

d = fun(0)
print('*******',d)

二分查找

我们首先引入这样一个问题:如果规定某一科目成绩分数范围:[0,100],现在小明知道自己的成绩,他让你猜他的成绩,如果猜的高了或者低了都会告诉你,用最少的次数猜出他的成绩,你会如何设定方案?(排除运气成分和你对小明平时成绩的了解程度)

①最笨的方法当然就是从0开始猜,一直猜到100分,考虑这样来猜的最少次数:1(运气嘎嘎好),100(运气嘎嘎背);

②其实在我们根本不知道对方水平的条件下,我们每一次的猜测都想尽量将不需要猜的部分去除掉,而又对小明不了解,不知道其水平到底如何,那么我们考虑将分数均分

  将分数区间一分为2,将第一次猜的分数将是50,当回答低了,将分数区间从【0,100】确定到【51,100】;

  当回答高了,将分数区间从【0,100】确定到【0,50】.这样一下子就减少了多余的50次猜想(从0数到49)(或者是从51到100)。

③那么我们假设当猜完50分之后答案是低了,那么我们需要在【51,100】分的区间内继续猜小明的分数,同理,我们继续折半,第二次我们将猜75分,当回答是低了的时候,我们将其分数区域从【51,100】确定到【76,100】;当回答高了的时候,我们将分数区域确定到【51,74】。这样一下子就减少了多余的猜想(从51数到74)(或者是从76到100)。

④就此继续下去,直到回复是正确为止,这样考虑显然是最优的

代码如下:

data_set = list(range(101))

def b_search(n,low,high,d):
    mid = int((low+high)/2)
    if low == high:
        print('not found')
        return

    if d[mid] > n:
       print('to left :', low,high ,d[mid])
       b_search(n, low, mid, d)
    elif d[mid] < n:
        print('to right :', low, high, d[mid])
        b_search(n, mid+1, high, d)
    else:
        print('find it ', d[mid])

b_search(88,0,len(data_set),data_set)

运行结果:

猜你喜欢

转载自www.cnblogs.com/lhly/p/11535848.html