Python基础之递归函数的应用


文章目录

  • 递归的定义
  • 循环和递归的区别
  • 递归函数的实例
    • 科赫雪花
    • 雪花晶片
    • 汉诺塔

递归的定义

函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子房间中,看到的影响就是递归的结果。
数学上有个经典的递归例子叫阶乘:

 n!=n(n-1)(n-2)......(1)

另一种表达阶乘的方式

      1   n=0
n!= n(n-1)! otherwise

这个定义说明0的阶乘 按定义是1,其他数字的阶乘定义为这个数字乘以比这个数字小1数的阶乘。递归不是循环,因为每次递归都会计算比它更小数的阶乘,直到0!。0!是已知的值,被称为递归的基例,当递归到底了,就需要一个能直接算出值的表达式。
阶乘的例子揭示了递归的两个关键特征。
(1)存在一个或多个基例,基例不需要再次递归,它是确定的表达式。
(2)所有递归链要以一个或多个基例结尾。
根据用户输入的整数n,计算并输出n的阶乘:

def fact(n):if n==0:return 1  #当n=0,fact()函数不再使用递归函数,返回值1else:return n*fact(n-1) #当n != 0,通过递归返回n与n-1阶乘的乘积
num=int(input("请输入一个整数:"))
print(fact(abs(num)))
--------------------------------------------------------------
输出结果:
请输入一个整数:5
120

递归遵循函数的语义,每次调用都会引起新函数的开始,表示它有本地变量值的副本,包括函数的参数。例如5!的递归调用,每次函数调用时,函数参数的副本会临时存储,递归中各函数再运算自己的参数,相互没有影响,当基例结束运算并返回值时,各函数逐层结束运算,想调用者返回计算结果。

循环和递归的区别

1、利用循环绘制大小不同的五角星。

import turtle
def draw_wjx(size):i=1while i<5:turtle.fd(size)turtle.rt(144)i +=1
def main():turtle.penup()turtle.backward(200)turtle.pendown()turtle.pensize(3)turtle.pencolor("red")j=200while j<=300:draw_wjx(j)j +=50turtle.done()main()

2、利用递归绘制不同大小的五角星

import turtle
def draw_wjx2(size):i=1while i<5:turtle.fd(size)turtle.rt(144)i +=1size+=50if size <=300:draw_wjx2(size) #递归
def main():turtle.penup()turtle.backward(200)turtle.pendown()turtle.pensize(3)turtle.pencolor("red")draw_wjx2(200)turtle.done()main()

总结:循环和递归的区别
循环由已知推未知,不断向后。
递归由未知寻找已知,不断向前,递归的实质是出入栈,效率较低。

递归函数的实例

科赫雪花

科赫雪花绘制方法:
(1)正整数n代表科赫雪花的阶数,表示生成科赫雪花过程的操作次数。科赫雪花初始化阶数为0,表示一个长度为L的直线。
(2)将直线L等分成3段,每段长度为L/3。
(3)中间一段用边长为L/3的等边三角形的两个边代替,这样得到1阶的科赫雪花曲线。
(4)重复前面(2)(3)的操作。

import turtle
def draw_koch(size,n):if n == 1:turtle.fd(size)   #  1阶的科赫雪花曲线就是一条直线else:for angle in [0,60,-120,60]:  # turtle在“尖”的四条线上改变的角度,分别为0°,60°,-120°,60°turtle.left(angle) # 对应上边四个角度,一共需要转4次弯,画出本阶的四条线,draw_koch(size/3,n-1)# 每个角度下的一个边,对应低一阶的科赫雪花曲线的“尖”;def main():turtle.setup(800,400)turtle.speed(0)turtle.penup()turtle.goto(-300,-50)turtle.pendown()turtle.pensize(2)draw_koch(200,4)turtle.hideturtle() #将光标隐藏main()

输出结果

前面的代码只是完成一个由“尖”组成的“边”,并不是完整的科赫雪花曲线。
完整的科赫雪花曲线由3个“边”组成,转动120度,使得科赫雪花曲线能围城一个三角形,形成最终的科赫雪花效果。

import turtle
def draw_koch(size,n):'''科赫曲线--一个由“尖”组成的“边”'''if n == 1:turtle.fd(size)else:for angle in [0,60,-120,60]:turtle.left(angle)draw_koch(size/3,n-1)
def draw_into():'''画笔初始化'''turtle.setup(600,600)turtle.speed(0)turtle.penup()turtle.goto(-200,100)turtle.pendown()turtle.pensize(2)def main(size,n): '''完整的n阶科赫雪花曲线'''draw_into()draw_koch(size,n)  # 完整的科赫雪花曲线由3个“边”组成。turtle.right(120)#转动120度,使得科赫曲线能围城一个三角形,形成最终的科赫雪花draw_koch(size,n)turtle.right(120)draw_koch(size,n)turtle.hideturtle()main(400,5)

输出的结果

根据科赫雪花绘制的方法绘制雪花晶片

雪花晶片


(1)当阶数为1时,画出一条直线L。
(2)当阶数大于1时,先将直线二等分,即L/2,左转60度,画出长度L/3的直线,再沿着直线移动-L/3长度回到二等分的位置,再左转-120度,画出长度L/3的直线,再沿着直线移动-L/3长度回到二等分的位置,最后左转60度,再进行二等分。

import turtle
def draw_snow(size,n):if n == 1: turtle.fd(size)  #当n=1阶时,绘制直线else:draw_snow(size/2,n-1) #当n>1阶时,将直线进行二等分 for  angle in [60,-120]:turtle.left(angle)# 左转60度,画出长度L/3的直线,再沿着直线移动-L/3长度回到二等分的位置,draw_snow(size/3,n-1)turtle.fd(-size/3)turtle.left(60) #最后左转60度draw_snow(size/2,n-1) #再进行二等分
def draw_into():'''画笔初始化'''turtle.setup(600,600)turtle.speed(0)turtle.penup()turtle.goto(0,0)turtle.pendown()turtle.pensize(2)turtle.left(90)def main(size,n):draw_into()draw_snow(size,n)turtle.hideturtle()main(200,5)

输出结果:

绘制6片晶片形成完整的晶片雪花效果

import turtle
def draw_snow(size,n):
'''绘制晶片'''if n == 1:turtle.fd(size)else:draw_snow(size/2,n-1)for  angle in [60,-120]:turtle.left(angle)draw_snow(size/3,n-1)turtle.fd(-size/3)turtle.left(60)draw_snow(size/2,n-1)
def draw_into():'''画笔初始化'''turtle.setup(600,600)turtle.speed(0)turtle.penup()turtle.goto(0,0)turtle.pendown()turtle.pensize(2)turtle.left(90) #将画笔朝上def main(size,n):draw_into()i=1while i <=6: #绘制6片晶片turtle.goto(0,0) #每次回到原点位置绘制draw_snow(size,n)turtle.right(60) #每片晶片的角度60度,绘制6次,形成完整的雪花晶片turtle.hideturtle() #每片绘制完将光标隐藏turtle.done() #结束绘制main(200,5) #直线长度为200, 5阶的雪花晶片

输出结果

汉诺塔

汉诺塔源于真实的故事,在世界某个地方有个很虔诚的宗教组织,期中僧侣维护着一项神圣任务:保持宇宙时间。在时间的最开始,僧侣在平台上竖立了3个垂直杆,在最左侧上有64个不同半径的金色同心圆盘,直径较大的圆盘堆放在下方,形成金字塔样的整体外观,僧侣们的任务是将有所圆盘从最左侧杆子移动到最右侧杆子,这个宗教认为当僧侣们完成任务的时候,万事万物将会化为乌有,宇宙结束。为了保持神圣的顺序,僧侣们移动圆盘需要尊从特定的规则,一次只能移动一个盘子,盘子只能在3个杆子之间移动,更大的盘子不能放在更小的盘子上面。
实现把 A 的 n 个盘子移动到 C(盘子编号是 [1, n] ),要求每次只能移动1个盘子,大盘子只能放在小盘子下面。
1、1个盘子移动时

直接从A移到C上
2、2个盘子移动时

此时借助中间B杆子,盘子1移到B杆子,盘子2移到C杆子,再将B杆子中的盘子1移到C杆子上。即A->B,A->C,B->C。
3、3个盘子移动时

借助中间B杆子,盘子1从A杆移到C杆子,盘子2从A杆移到B杆,再将盘子1从C杆移到B杆中,将盘子3从A杆移到C杆,将盘子1从B杆移到A杆,将盘子2从B杆移到C杆,最后将盘子1从A杆移到C杆。即A->C,A->B,C->B,A->C (此时最大的盘子已经移动到C。接下来剩下的要从B经过A(新的过度柱)移动到C,即B->A,B->C,A->C。
4、思路
(1)当 n == 1时,直接将盘子从 A 移动到C
(2)当 n > 1时,可以拆分成3大步骤
①将 n– 1 个盘子从 A 移动到B,可以利用递归调用

②将编号n最大的盘子从A移到C

③ 将编号n-1的盘子从B移到C,可以利用递归调用

def hanoi(n,A,B,C):         #定义汉诺塔函数,参数n是圆盘数,A、B、C是3根柱if n==1:                 #判断圆盘数,如果等于1,递归条件print("第{}个盘子从{}---->{}".format(n,A,C))   # 直接将A柱上的圆盘移动到C柱上else:  #否则,进行递归移动hanoi(n-1,A,C,B)  #递归将A柱最上方的n-1个盘子落在B柱print("第{}个盘子从{}---->{}".format(n,A,C))     # 将最大的盘子移到C柱上hanoi(n-1,B,A,C)  #递归将B柱上的n-1个盘子,移到C柱上hanoi(3,'A','B','C')               #调用函数

第1个盘子从A---->C
第2个盘子从A---->B
第1个盘子从C---->B
第3个盘子从A---->C
第1个盘子从B---->A
第2个盘子从B---->C
第1个盘子从A---->C

递归函数定义、递归应用案例-科赫雪花/雪花晶片/汉诺塔相关推荐

  1. 两个经典递归问题:菲波那契数列 + 汉诺塔

    一.递归问题的处理步骤 1)抽象出递归公式:对实际问题进行部分穷举,抽象出递归关系(关键),并列出"递归表达式" 2)确定递归出口:找出递归调用终止点 二.菲波那契数列 实际问题: ...

  2. 第023、024讲:递归:这帮小兔崽子、汉诺塔

    动动手 0. 使用递归编写一个十进制转换为二进制的函数(要求采用"取2取余"的方式,结果与调用bin()一样返回字符串形式). def Bin(x):if x==0:return ...

  3. 【小甲鱼Python】递归:这帮小兔崽子、汉诺塔课后作业

    笔记 斐波那契数列 汉诺塔 有64个盘子,三根柱子(从左至右依次为x,y,z柱).要求将这64个盘子从x移动到z上. 解决思想: 首先,将三根柱子依次分为起始柱,辅助柱和目标柱.在移动过程中,这三个柱 ...

  4. 《零基础入门学习Python》第023、024讲:递归:这帮小兔崽子、汉诺塔

    目录 动动手 0. 使用递归编写一个十进制转换为二进制的函数(要求采用"取2取余"的方式,结果与调用bin()一样返回字符串形式). 1. 写一个函数get_digits(n),将 ...

  5. FishC笔记—23,24 讲 递归:这帮小兔崽子,汉诺塔

    本期内容详解: 斐波那契数列的两种实现方式: 迭代的方式: def fab(n): n1 = 1 n2 = 1 n3 = 1 if n < 1: n = int(input('输入有误,请重新输 ...

  6. 简洁笔记-Java数据结构基础(5.递归和斐波那契数列、汉诺塔)

    什么是递归 递归简单来说就是方法调用自己 例子1: 从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山.. 例子2:美女拿着自己的照片, ...

  7. [Python]小甲鱼Python视频第023~024课(递归:这帮小兔崽子、汉诺塔)课后题及参考解答...

    # -*- coding: utf-8 -*- """ Created on Thu Mar 7 19:44:16 2019@author: Administrator ...

  8. 第023、024讲:递归:这帮小兔崽子、汉诺塔 | 课后测试题及答案

    动动手: 0. 使用递归编写一个十进制转换为二进制的函数(要求采用"取2取余"的方式,结果与调用bin()一样返回字符串形式). def Dec2Bin(dec):result = ...

  9. Python——递归:这帮小兔崽子、汉诺塔

    def dec2bin(dec):temp = []result = ''while dec:quo = dec % 2dec = dec // 2temp.append(quo)while temp ...

  10. 深度理解递归,手撕经典递归问题(汉诺塔,青蛙跳台阶),保姆级教学。

    目录 序言: 一.函数递归( recursion) 二.递归的两个必要条件 三.递归小问题 (1)接受一个整型值(无符号),按照顺序打印它的每一位 (2)编写函数不允许创建临时变量,求字符串的长度(利 ...

最新文章

  1. NioEventLoop 的实例化过程
  2. POJ 3581 Sequence ——后缀数组 最小表示法
  3. 已经安装完成mysql后wamp怎么配置
  4. html 图像 ppt,用HTML设置的文本和图像.ppt
  5. SpringBoot之SpringMVC自动配置
  6. HTML5拖放API(代码展示)
  7. .JQuery中的Ajax
  8. PHP文件操作-读取数据库文件路径复制到另一个目录
  9. iptv错误代码2003什么意思_IPTV部分错误代码及原因解释
  10. 大众点评美食评论爬虫
  11. Python中计算二重积分
  12. 机器学习十大算法实现python代码汇总
  13. DTCC 2018大会归来
  14. python计算对数收益率_对数收益率怎么转成年化收益率?怎么计算夏普比率?
  15. 大学生微信小程序项目总结
  16. 最小生成树求最大比率 UVALive - 5713
  17. 关于四阶魔方中心块还原
  18. 7.中文句法依存分析
  19. 零基础入门数据挖掘-Task3 特征工程
  20. 法国内政部选择由金雅拓保护该国关键的通信移动网络

热门文章

  1. appfuse mysql_Appfuse中文教程
  2. Selenium和Firefox对应版本及注意事项
  3. U盘制作微pe工具箱(实战)
  4. [SC66 Android9.0]修改Android序列号
  5. 4G+5G多卡聚合(弱网通信)路由器视频传输最佳选择
  6. 米思齐(Mixly)初体验—触摸式开关
  7. ISO/IEC 27000官方文档系列
  8. 圈粉无数!被称为B站“新垣结衣”的UP主,如何收获Z世代年轻人的喜爱?
  9. 谷歌浏览器安装插件的方法步骤
  10. 计算机上直接拆硬盘在硬盘盒中使用,触目惊心 西数1TB移动硬盘拆解_硬盘/光驱盒_移动存储-中关村在线...