数据结构与算法Python版之北大慕课笔记(二)
一、递归基础
1. 递归三定律
- 递归算法必须有一个基本结束条件(最小规模问题的直接解决)
- 递归算法必须能改变状态向基本结束条件演进(减小问题规模)
- 递归算法必须调用自身(解决减小了规模的相同问题)
2. 递归版数列求和
代码思路: 数列的和 = 首个数 + 余下数列的和 ,如果数列包含的数少到只有1个的话,它的和就是这个数了。
代码实现:
# 递归版数列求和:
def listsum(numList):
if len(numList) == 1:
return numList[0]
else:
return numList[0] + listsum(numList[1:])
print(listsum([1,3,5,7,9]))
3. 递归版任意进制转换
代码思路:
-
假设是要转换为十进制,比十小的整数转换为十进制,直接查表就可以得到,比十大的整数就想办法拆成一系列比十小的整数,逐个查表。
-
所以递归基本结束条件就是小于十的整数,拆解整数的过程就是向基本结束条件演进的过程。
-
拆解过程分为两步:1. 除以“进制基base” (// base);2. 对“进制基”求余数(% base)。
-
此时问题就分解为:1. 余数总小于“进制基base”,是基本结束条件,可直接查表转换;2. 整数商成为更小规模问题,通过递归调用自身解决。
代码实现:
# 递归版整数转换为任意进制:
def toStr(n,base):
convertString = "0123456789ABCDEF"
# print(convertString[5])
if n < base:
return convertString[n] # 最小规模
else:
return toStr(n//base,base) + convertString[n%base] # 减小规模,调用自身
print(toStr(1453,16))
4. 递归调用的实现和深度限制
- 当一个函数被调用的时候,系统会把调用时的现场数据压入到系统调用栈,每次调用,压入栈的现场数据成为栈帧,当函数返回时,要从调用栈的栈顶取得返回地址,恢复现场,弹出栈帧,按地址返回。
-
在Python内置的sys模块可以获取和调整最大递归深度。
import sys sys.getrecursionlimit(10000)
二、递归可视化:分形树
1. 递归可视化
import turtle
# 正方形:
t = turtle.Turtle()
for i in range(4):
t.towards(100)
t.right(90)
turtle.done()
# 五角星:
t = turtle.Turtle()
t.pencolor("red")
t.pensize(3)
for i in range(5):
t.towards(100)
t.right(144)
t.hideturtle()
turtle.done()
# 螺旋线:
t = turtle.Turtle()
def drawSpiral(t,lineLen):
if lineLen > 0:
t.forward(lineLen)
t.right(90)
drawSpiral(t,lineLen-5)
drawSpiral(t,200)
turtle.done()