二叉树遍历(如DFS)是否符合通用递归算法的两步归纳求解模式
二叉树DFS遍历与通用递归模式的对应关系
二叉树的DFS遍历完全符合你提到的两步递归模式,只需要先明确定义「问题规模」即可,对应逻辑拆解如下:
1 明确递归问题的规模定义
我们将当前需要遍历的子树的总节点数N作为问题规模,遍历的目标是输出该子树所有节点的先序序列。
2 对应递归模式的两个步骤
2.1 步骤1:最小输入的基例求解
最小输入对应两种边界场景,你提到的「仅用None作为基例是否合理」的疑问本质是写法简化的问题:
- 最小规模
N=0:对应空树(root == None),解为不需要任何输出,直接返回,这是所有递归的终止边界 - 次小规模
N=1:对应只有根节点的子树(左右子树都为空),解为直接打印当前节点值。常规写法没有显式写这个基例,是因为调用左右子树的DFS都会命中N=0的基例直接返回,最终执行效果和单独写N=1基例完全一致,只是写法更简洁。
如果你想显式写出N=1的基例,改写后的代码也能正常运行,和原版本功能完全等价:
def DFS(root): # 基例1:N=0,空树 if root == None: return # 基例2:N=1,单个节点 if root.left == None and root.right == None: print(root.value) return # 递归步骤 print(root.value) DFS(root.left) DFS(root.right)
2.2 步骤2:更大规模的递归求解
对于规模为N=k(k>=2)的子树,我们可以将它拆分为3部分:根节点(1个节点)、左子树(规模a)、右子树(规模b),满足a + b + 1 =k,显然a <k、b <k,符合「已知更小规模同问题解」的前提。
此时当前规模k的先序遍历解的合并逻辑为:
- 先输出根节点的值(就是你提到的第四行print语句,属于递归步骤的合并逻辑,本来就不属于基例,所以会在每一层子树遍历中执行)
- 拼接左子树的先序遍历结果(调用
DFS(root.left),已经是正确解) - 拼接右子树的先序遍历结果(调用
DFS(root.right),已经是正确解)
拼接后的结果就是当前规模k的子树的正确先序遍历序列,完全符合递归模式的第二步要求。
3 补充说明
你提到的斐波那契数列的递归是「单分支缩小规模」(从k到k-1、k-2),而二叉树遍历是「多分支缩小规模」(从k到更小的a和b),只是规模缩小的路径不同,本质都是符合归纳式递归的通用模式的。
内容的提问来源于stack exchange,提问作者Vahram Poghosyan
相关产品推荐
相关产品推荐

