Python学习札记(十四) Function4 递归函数 & Hanoi Tower
reference:递归函数
Note
1.在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
eg.计算阶乘:
#!/usr/bin/env python3
def my_func(n) :
if n == 1 :
return 1
return n * my_func(n-1)
output:
>>> from function4 import my_func
>>> my_func(1)
1
>>> my_func(2)
2
>>> my_func(3)
6
>>> my_func(4)
24
>>> my_func(5)
120
>>> my_func(10)
3628800
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
func(5)的计算过程:
===> func(5)
===> 5 * func(4)
===> 5 * (4 * func(3))
===> 5 * (4 * (3 * func(2)))
===> 5 * (4 * (3 * (2 * func(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
2.使用递归函数需要注意 防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
eg. my_func(1000)
output:
File "/Users/wasdns/Desktop/Python-Learning/function/function4.py", line 4, in my_func
if n == 1 :
RecursionError: maximum recursion depth exceeded in comparison
3.解决递归调用栈溢出的方法是进行尾递归优化:
尾递归是指:1.在函数返回的时候,调用自身本身;2.return语句不能包含表达式。
这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
也就是说,尾递归优化重复调用一个帧栈,节省了大量运行时栈空间。
eg.
def my_func_2(num, product) :
if num == 1 :
return product
return my_func_2(num-1, num*product)
output:
>>> my_func_2(5, 1)
120
计算过程:
===> func_2(5, 1)
===> func_2(4, 5)
===> func_2(3, 20)
===> func_2(2, 60)
===> func_2(1, 120)
===> 120
练习
Hanoi Tower解法请参考:Hanoi Tower。
抽象步骤:
1.将A柱中n-1个柱子搬到B柱。
2.将A柱中第n个柱子搬到C柱。
3.将A柱视作B柱,B柱视作A柱,重复上述两个步骤。
一个思考问题的关键是,忽略细节。在思考的时候,需要把函数视作一个整体功能,即将n个盘子从a移动到b,忽略其细节对于思考是一件很重要的事情。
def move(n, a, b, c) :
if (n == 1) : # A move last one to C
print(a, '=>', c)
return
else :
move(n-1, a, c, b) # from A move n-1 to B
move(1, a, b, c) # A move last one to C
move(n-1, b, a, c) # from B move n-1 to C
>>> move(3, 'A', 'B', 'C')
A => C
A => B
C => B
A => C
B => A
B => C
A => C
2017/2/3
Python学习札记(十四) Function4 递归函数 & Hanoi Tower的更多相关文章
- Python学习札记(十二) Function3 函数参数一
参考:函数参数 Note 1.Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以 ...
- Python 学习 第十四篇:命名元组
Python的元组不能为元组内部的数据进行命名,而 collections.namedtuple 可以来构造一个含有字段名称的元组类,命名元组可以通过逗号+字段名来获取元素值: collections ...
- Python学习(十四) —— 并发编程
一.进程的概念 进程即正在执行的一个过程,进程是对正在运行的程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念.操作系统的其它所有内容都是围绕进程的概念展开的. #必备的理论基础 #一 ...
- Python学习札记(十五) 高级特性1 切片
参考: 高级特性 切片 Note 1.掌握了Python的基础语法之后,就可以写出很多很有用的程序了,比如打印1-90的奇数: #!/usr/bin/env python3 L = [] n = 1 ...
- python 学习笔记十四 jQuery案例详解(进阶篇)
1.选择器和筛选器 案例1 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- python学习第十四天 -面向对象编程基础
python也是支持面向对象编程的.这一章节主要讲一些python面向对象编程的一些基础. 什么是面向对象的编程? 1.面向对象编程是一种程序设计范式 2.把程序看做不同对象的相互调用 3.对现实世界 ...
- python学习笔记(十 四)、web.py
使用web.py 通过python进行网页的编写,下面我们来简单了解一哈web.py 的使用 1 url处理 使用特定的url结构来解析我们发送的请求.如下面所示: urls = ( '/login' ...
- Python学习第十四篇——类初步使用及面向对象思想
class Restaurant(): def __init__(self,restaurant_name,cuisine_type): self.name = restaurant_name sel ...
- python学习笔记十四:wxPython Demo
一.简介 wxPython是Python语言的一套优秀的GUI图形库,允许Python程序员很方便的创建完整的.功能键全的GUI用户界面. wxPython是作为优秀的跨平台GUI库wxWidgets ...
随机推荐
- new Date()的浏览器兼容性问题
在页面中,我们使用了一个时间上的组件来开发时间选择框,在Chrome下是可以正常运行的,但是发现在IE下是无法正常工作的. 问题出在哪里呢? js从时间获取的时间字符串如果是"-" ...
- Linux 搭建Git服务器
安装Git yum install -y git git --version 创建 Git 用户 sudo adduser git // 设置密码 passwd git 导入公钥 find / -na ...
- SOI简单体验
导语 arcgis for server10.3.1中提供了一个新的功能叫做soi.本文简单的介绍soi概念,实现,在使用过程中的注意事项.阅读本文和使用soi需要以下先决条件 SOI是ArcGIS ...
- UNIX或LINUX时间戳转时间
ORACLE: select TO_DATE('19700101', 'yyyymmdd') + 1481148929 / 86400 + TO_NUMBER(SUBSTR(TZ_OFFSET(ses ...
- 剑指Offer——最小的K个数
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 分析: 建一个K大小的大根堆,存储最小的k个数字. 先将K个数进堆 ...
- POJ2318:TOYS(叉积判断点和线段的关系+二分)&&POJ2398Toy Storage
题目:http://poj.org/problem?id=2318 题意: 给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数.(其中这些线段 ...
- javascript 中的 parameter vs arguments
像往常一样简单粗暴地看码: A parameter is the variable which is part of the method’s signature (method declaratio ...
- centos7安装rabbitmq并简单使用
先安装erlang rpm -Uvh http://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el7.centos.x86_64.rpm 安装rab ...
- 项目总结之HashMap问题
在项目中我需要用另一个项目的中的方法,在另一个项目中的方法返回值是一个hashmap,返回的不是一个hashMap中存的对象而是Object对象.在一个项目中调用另一个项目中的方式是直接引入另一个项目 ...
- 如何获知PHP程序占用多少内存(复制)
想要知道编写的 PHP 脚本需要占用多少内存么?很简单,直接使用 PHP 查看当前分配给 PHP 脚本的内存的函数 memory_get_usage() 就可以了 下面是使用示例: 复制代码 代码如下 ...