您的位置:首页 > 编程语言 > Python开发

python基础知识- 递归函数

2018-03-29 21:22 218 查看
递归函数
定义:一个函数在内部自身调用自身本身。
优点:定义简单,逻辑清晰。
注意:
防止栈溢出。(函数的调用是通过栈的数据结构实现的,每当进入一个函数调用,栈就会增加一层栈帧,每当函数返回,栈就会减少一层栈帧。)
解决方法:通过尾递归优化。在函数返回的时候,调用自身,return语句不能包含表达式。这样,编译器或解释器就可以把尾递归做优化,使函数不论调用多少次,都只占用一个栈帧,不会出现栈溢出情况。
# 递归函数# 计算阶乘 n!
def fact(n):    if n == 1:       return 1    return n * fact(n - 1)
# 测试结果>>> fact(100)93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000>>> fact(1000)Traceback (most recent call last):def fact(n):RecursionError: maximum recursion depth exceeded in comparison使用尾递归:

def fact(n):    return fact_iter(n, 1)
def fact_iter(num, product):    if num == 1:        return product    return fact_iter(num -  1, num * product)

大多数编程语言没有对尾递归做优化,Python解释器也没有做优化,因此,改动之后程序也会导致栈溢出。

小结

使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。练习:
# -*- coding:utf-8 -*-# 汉诺塔递归函数实现
def move(n, a, b, c):    if n == 1:        print('move', a, '-->', c)    else:        move(n-1, a, c, b)        move(1, a, b, c)        move(n-1, b, a, c)

# 测试:#move(3, 'A', 'B', 'C')#move A --> C#move A --> B#move C --> B#move A --> C#move B --> A#move B --> C#move A --> C转载来自:廖雪峰的官方网站

def fact(n):    return fact_iter(n, 1)
def fact_iter(num, product):    if num == 1:        return product    return fact_iter(num -  1, num * product)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: