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解释器也没有做优化,因此,改动之后程序也会导致栈溢出。
# -*- 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)
定义:一个函数在内部自身调用自身本身。
优点:定义简单,逻辑清晰。
注意:
防止栈溢出。(函数的调用是通过栈的数据结构实现的,每当进入一个函数调用,栈就会增加一层栈帧,每当函数返回,栈就会减少一层栈帧。)
解决方法:通过尾递归优化。在函数返回的时候,调用自身,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)
相关文章推荐
- Python基础知识(五)--数据类型
- 【脚本语言系列】关于Python基础知识推导式,你需要知道的事
- 基础知识:python模块的导入
- Python 第一章 基础知识(9) 字符串
- 01月24日【Python3 基础知识】
- Python第一阶段:基础知识讲解
- Python基础知识总结
- Python程序设计1——基础知识
- python基础知识之常用函数
- Python基础知识(五)--数据类型
- Python基础知识——python中的if __name__ == "__main__"运用
- Python基础知识:python模块的引入方法
- 学学python(1)一些基础知识点
- python基础知识==各类型转换及遍历(字符,list,字典)
- Python基础知识思维导图
- python爬虫基础知识之选择器
- Python--基础知识
- python基础知识——列表、元组
- python 学习笔记之基础知识(1)
- python基础知识纵览(下)