鱼C论坛

 找回密码
 立即注册
查看: 2000|回复: 4

关于turtle用递归函数画树的问题

[复制链接]
发表于 2019-5-3 17:14:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import turtle
  2. def tree(n):
  3.     if n > 5:
  4. # 右边树
  5.         turtle.forward(n)
  6.         turtle.right(20)
  7.         tree(n-15)
  8. # 这里画完右边树后,笔的位置应该在最右边顶点上,为什么不用写返回的语句,就可以直接画左边树?
  9. # 左边树
  10.         turtle.left(40)
  11.         tree(n-15)
  12. # 返回
  13.         turtle.right(20)
  14.         turtle.backward(n)
  15. def main():
  16.     turtle.left(90)
  17.     turtle.backward(50)
  18.     tree(80)
  19.     turtle.exitonclick()
  20. if __name__ == '__main__':
  21.     main()
复制代码



请教各位大佬,上面语句画完右边树枝后,笔的位置应该在最右边顶点上,为什么不用写返回到上一个节点的语句,就可以直接画左边树枝?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-5-3 18:00:19 | 显示全部楼层
递归
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-5-3 18:44:40 | 显示全部楼层

我也知道是递归呀  
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-3 20:40:27 | 显示全部楼层
递归是会返回去的,画完右边树枝后,笔的位置在最右边顶点上,然后会一层一层到回去,一直回到第一个右树枝,这个就可以直接画左边树枝
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2019-5-4 12:06:33 | 显示全部楼层
本帖最后由 stormc 于 2019-5-4 14:46 编辑
shake_a_tree@16 发表于 2019-5-3 20:40
递归是会返回去的,画完右边树枝后,笔的位置在最右边顶点上,然后会一层一层到回去,一直回到第一个右树枝 ...


首先感谢大佬的耐心分析和回答。
不过还是有点似懂非懂。尝试把每一步操作后面进行打印注释,(递归调用前后均写打印注释),为减小步骤,改为tree(40),好像有点领悟到大佬的这个一层一层回去的具体意思

n的值有个回滚的过程。 #右边树 的代码运行完后, # 左边树 这段的第一次递归实际跳出来了,未运行(n不大于5),然后继续运行# 返回 段,也就是返回语句。

但是,按照正常写程序的思路,单个步骤其实就是,右树画完,返回,左树,返回。为何具体到写代码的时候就是 右树,左树,返回 ,那个“右树”和“左树”之间的“返回”代码能考虑到其实是不用写的?

修改后代码和打印消息如下:
  1. import turtle
  2. def tree(n):
  3.     if n > 5:
  4. # 右边树
  5.         turtle.forward(n), print("段1右树:前进",n,"---此时n的值为:",n)
  6.         turtle.right(20), print("段1右树:右转 20","---此时n的值为:",n)
  7.         print("段1右树:开始调用tree(n-15)","---此时n的值为:",n), tree(n-15) , print("段1右树:调用tree(n-15)结束","---此时n的值为:",n)
  8. # 这里画完右边树后,笔的位置应该在最右边顶点上,为什么不用写返回的语句,就可以直接画左边树?
  9. # 左边树
  10.         turtle.left(40) , print("段2左树:左转 40","---此时n的值为:",n)
  11.         print("段2左树:开始调用tree(n-15)","---此时n的值为:",n), tree(n-15) , print("段2左树:调用tree(n-15)结束","---此时n的值为:",n)
  12. # 返回
  13.         turtle.right(20) ,  print("段3返回:右转 20","---此时n的值为:",n)
  14.         turtle.backward(n) , print("段3返回:后退", n,"---此时n的值为:",n)
  15. def main():
  16.     turtle.left(90)
  17.     turtle.backward(40)
  18.     tree(40)
  19.     turtle.exitonclick()
  20. if __name__ == '__main__':
  21.     main()
复制代码



段1右树:前进 40 ---此时n的值为: 40   
段1右树:右转 20 ---此时n的值为: 40
段1右树:开始调用tree(n-15) ---此时n的值为: 40
段1右树:前进 25 ---此时n的值为: 25
段1右树:右转 20 ---此时n的值为: 25
段1右树:开始调用tree(n-15) ---此时n的值为: 25
段1右树:前进 10 ---此时n的值为: 10
段1右树:右转 20 ---此时n的值为: 10
段1右树:开始调用tree(n-15) ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 10
段2左树:左转 40 ---此时n的值为: 10            
段2左树:开始调用tree(n-15) ---此时n的值为: 10  #哦, 原来这里左树未满足if语句条件,其实未执行,相当于先执行了下面的返回语句。  
段2左树:调用tree(n-15)结束 ---此时n的值为: 10   #哦, 原来这里左树未满足if语句条件,其实未执行,相当于先执行了下面的返回语句。

段3返回:右转 20 ---此时n的值为: 10
段3返回:后退 10 ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 25
段2左树:左转 40 ---此时n的值为: 25
段2左树:开始调用tree(n-15) ---此时n的值为: 25
段1右树:前进 10 ---此时n的值为: 10
段1右树:右转 20 ---此时n的值为: 10
段1右树:开始调用tree(n-15) ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 10
段2左树:左转 40 ---此时n的值为: 10
段2左树:开始调用tree(n-15) ---此时n的值为: 10
段2左树:调用tree(n-15)结束 ---此时n的值为: 10
段3返回:右转 20 ---此时n的值为: 10
段3返回:后退 10 ---此时n的值为: 10
段2左树:调用tree(n-15)结束 ---此时n的值为: 25
段3返回:右转 20 ---此时n的值为: 25
段3返回:后退 25 ---此时n的值为: 25
段1右树:调用tree(n-15)结束 ---此时n的值为: 40
段2左树:左转 40 ---此时n的值为: 40
段2左树:开始调用tree(n-15) ---此时n的值为: 40
段1右树:前进 25 ---此时n的值为: 25
段1右树:右转 20 ---此时n的值为: 25
段1右树:开始调用tree(n-15) ---此时n的值为: 25
段1右树:前进 10 ---此时n的值为: 10
段1右树:右转 20 ---此时n的值为: 10
段1右树:开始调用tree(n-15) ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 10
段2左树:左转 40 ---此时n的值为: 10
段2左树:开始调用tree(n-15) ---此时n的值为: 10
段2左树:调用tree(n-15)结束 ---此时n的值为: 10
段3返回:右转 20 ---此时n的值为: 10
段3返回:后退 10 ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 25
段2左树:左转 40 ---此时n的值为: 25
段2左树:开始调用tree(n-15) ---此时n的值为: 25
段1右树:前进 10 ---此时n的值为: 10
段1右树:右转 20 ---此时n的值为: 10
段1右树:开始调用tree(n-15) ---此时n的值为: 10
段1右树:调用tree(n-15)结束 ---此时n的值为: 10
段2左树:左转 40 ---此时n的值为: 10
段2左树:开始调用tree(n-15) ---此时n的值为: 10
段2左树:调用tree(n-15)结束 ---此时n的值为: 10
段3返回:右转 20 ---此时n的值为: 10
段3返回:后退 10 ---此时n的值为: 10
段2左树:调用tree(n-15)结束 ---此时n的值为: 25
段3返回:右转 20 ---此时n的值为: 25
段3返回:后退 25 ---此时n的值为: 25
段2左树:调用tree(n-15)结束 ---此时n的值为: 40
段3返回:右转 20 ---此时n的值为: 40
段3返回:后退 40 ---此时n的值为: 40
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-15 15:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表