覆盖的知识点
语法
- 递归
数据结构
- 链表
- 栈&&队列
- 二叉树
- BST
- AVL
- 线段树
- 红黑
- 堆
- 二叉堆
- 图
算法
- 排序
- BFS/DFS
- Dijkstra/Floyd
- LCA
- 并查集
基础语法
基础题
递归
-
将递归看作深度不定,循环体可拆开的循环
递归类似于循环,但循环一般(不全是)要求给定一个深度,也就是循环次数。而且,循环结构遵循:“判断”->“循环体”->“判断”->…的流程,除非中途跳出,循环体必须从头开始全部执行。
相对而言,递归基本上不需要给定深度(当然还是需要跳出递归的判断条件的),而且也可以在执行了一部分代码后,先进入下一层递归,等到递归全部处理完后才执行剩余的代码。
其实,尾递归(也就是递归函数在自己的末尾)等价于循环,是可以简单地用循环重写的。 -
从伪代码角度去理解
另一方面,如果无法理解递归函数的执行逻辑,就尝试脱离具体的语句,将函数抽象为伪代码的形式。一般而言,递归函数的格式为:
whatever_type recursion( paraments ){
//terminal condition ( return before enter the next recursion )
//what need to do before
recursion( new_paraments );
// what need to do after recursions
return sth.;// if you need
}
这样抽象考虑的重点在于,不要“进入”递归函数,只要知道递归函数实现了它要做的事情就足够了,具体怎么实现的,在此时不需要考虑。这样,能够帮助我们厘清递归前后要做什么,以及参数要如何更新。
以汉诺塔为例:(这里借用wiki的代码)
# 北京八维研修学院人工智能学院1906A班学员
# 2021年1月20日 星期三 下午17:28
# 听许朋飞老师讲解python基础之递归函数后做出
# 不足之处请各位不吝赐教
# 本代码侧重展示解题细节,没有刻意追求效率
xpillars = {
'A', 'B', 'C'} # 汉诺塔的三个柱子
def xhanoi(xtop, xbottom, xsrc='A', xdest='C'):
'''
解汉诺塔
:param xtop: 移动的“整体”的最顶层,只能是1或xbottom
:param xbottom: 移动的“整体”的最底层,正整数
:param xsrc: 从哪个柱子移动(起始柱子)
:param xdest: 移动到哪个柱子(目标柱子)
:return: None
'''
if not (xtop == 1 and xbottom >= xtop or 1 < xtop == xbottom) \
or not (xsrc in xpillars) \
or not (xdest in xpillars):
print('非法参数')
return
if xtop == xbottom: # 仅移动一个盘子
print(xtop, xsrc, '-->', xdest)
else: # 移动两个以上盘子
xaux = (xpillars - {
xsrc, xdest}).pop() # 三个柱子里用作“中转”的柱子
# 递归算法
xhanoi(1, xbottom - 1, xsrc, xaux) # 先把1到倒数第2个盘子移动到中转柱子
xhanoi(xbottom, xbottom, xsrc, xdest