python 之 递归

终于来到了这里,这是一座山,山那边都是神仙

定义:在一个函数里调用函数本身

最好的例子就是,求阶乘

def factorial(n):
    if n == 1:
        return 1
    elif n > 1:
        return n*factorial(n-1)



while True:
    n = input('n>>')
    n = int(n)
    print(factorial(n))

递归最大层数

上面金典的例子运行的很成功

下面再来一个,是一个古老的故事,说,从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢?

我们用代码开实现一下

def story():
    s = """
    从前有个山,山里有座庙,庙里老和尚讲故事,
    讲的什么呢?
    """
    print(s)
    
while True:
    story()

你运行了吗?

shit,他报错了,但是这个故事讲的很完美。

RecursionError: maximum recursion depth exceeded while calling a Python object
这个错误是说,这个程序运行的代码,超过了最大递归层数。

正如我们看到的,如果没有外界阻力,它会一直运行下去

# 添加参数,设置停止条件
def calc(n, count):
    print(n, count)
    if count < 5:
        return calc(n/2, count+1)
    else:
        return n
print(calc(188,0))

 

因为每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,直到内存被占满,然后死机。

所以限制了他的最大递归层数,一般就是999层,

当然这个数字是可以修改的,修改方法很冷门,一般也不会有人去修改它,

因为如果递归了999层都没有解决问题,那么,你该想想是不是代码写的太烂了,呵呵……..

递归的特性

1、递归必须要有一个结束条件,否则就是一个死循环,直到报错
2、每次进入更深一次递归时,递归的规模会比上次递归有所减小
3、递归的执行效率不高,递归层次过多会导致栈溢出

递归的作用

用于很多计算:斐波拉契数列,汉罗塔,多级评论树,二分查找,阶乘

二分查找例子

data_set = [1,3,4,6,7,8,9,10,11,13,14,16,18,19,21]
# data_set = list(range(101))


def b_search(n, low, high, d):
    mid = int((low + high) / 2)  # 中间值
    print(mid)
    if low == high:  # 第一位 和 最后一个 对比(索引的对比)
        print('not find')
        return
    if d[mid] > n:
        print('go left', low, high, d[mid])
        b_search(n, low, mid, d)
    if d[mid] < n:
        print('go right', low, high, d[mid])
        b_search(n, mid, high, d)
    else:
        print('find it', d[mid])  


b_search(16, 0, len(data_set), data_set)

尾递归

尾递归是对递归的优化,提高递归的效率,但是在python中并不支持,然并卵

优化:

在调用下次递归时,直接return自己,不保留外层函数的在内存中的数据,递归需要的只是这一层的信息,所以节省了内存,提高了效率

然而在python中,因为没有优化,我们鼓励使用迭代器来改写尾递归

(引用自知乎)

posted @ 2018-05-25 00:26  游小刀  阅读(283)  评论(0编辑  收藏  举报
levels of contents