递归
递归定义
解决问题的一种方法,将问题不断的分成更小的子问题,直到子问题可以用普通的方法解决。递归会使用一个不停调用自己的函数。
# 使用循环求和函数
def listsum(numList):
theSume = 0
for i in numList:
theSume = theSume + i
return theSume
# 使用递归
def listsum(numList):
# 退出语句
if len(numList) == 1:
return numList[0]
else:
# [1:]使用第一个元素之后的内容
return numList[0] + listsum(numList[1:])
递归三原则:
1.递归算法必须有基本情况(使算法停止递归的条件)
2.递归算法必须改变其状态并向基本情况靠近
3.递归算法必须递归的调用自己
递归的逻辑并不是循环,而是将问题分解成更小、更容易解决的子问题。
将整数转换成任意进制的字符串
将一个整数转换成以2~16为基数的字符串。
算法包括三个部分:
1.将原来的整数分成一系列仅有单数位的数
2.通过查表将单数位的数转换成字符串
3.连接得到的字符串,从而形成结果
# 进制转换
def toStr(n,base):
converString = "0123456789ABCDEF"
if n < base:
return converString[n]
else:
return toStr(n//base,base) + converString[n%base]
print(toStr(8,2))
# 使用栈
class Stack:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
rStack = Stack()
def toStr(n,base):
converString = "0123456789ABCDEF"
if n < base:
rStack.push(converString[n])
else:
rStack.push(converString[n%base])
toStr(n//base,base)
栈限定了函数所用变量的作用域,尽管反复调用相同的函数,但是每一次调用都会为函数局部变量创建新的作用域。
递归可视化
使用递归来绘制有趣团的例子。
'''
绘制小乌龟
使用turtle模块递归的绘制螺旋线
函数的基本情况是:要画的线的长度降为0,如果线的长度大于0,就让小乌龟向前移动len个单位距离,然后向右旋转90度,
'''
from turtle import *
# 创建小乌龟对象
myTurtle = Turtle()
# 创建绘制团的窗口
myWin = myTurtle.getscreen()
def drawSpiral(myTurtle,lineLen):
if lineLen > 0:
myTurtle.forward(lineLen)
myTurtle.right(90)
drawSpiral(myTurtle,lineLen-5)
drawSpiral(myTurtle,100)
# 进入等待模式,直到用户在窗口内再次点击之后
# 程序清理并退出
myWin.exitonclick()
绘制一颗分形树,分形的定义是不论方法多少倍来观察分形图,总是有相同的基本形状。即使是一根小细支也右和一整棵树一样的形状和特征。把树定义为树干,其上长着一颗向左生长和向右生长的子树,可以将树的递归定义运用到它的左右子树上。
# 绘制分形树
def tree(branchLen,t):
if branchLen >5:
t.forward(branchLen)
# 向右转向20
t.right(20)
tree(branchLen-15,t)
# 向左转向20,同时抵消之前向右转向的20
t.left(40)
tree(branchLen-10,t)
t.right(20)
t.backward(branchLen)
t = Turtle()
myWin = t.getscreen()
t.left(90)
t.up()
t.backward(300)
t.down()
t.color('green')
tree