【发布时间】:2021-11-03 02:31:55
【问题描述】:
对于大小为 N 的问题的许多递归解决方案都遵循这种模式:
第 1 步:求解最小输入的问题(例如,n = 1)
第 2 步:给定大小为 n = k-1 (k
我们可以看到它的归纳性质,这就是为什么我们通常使用归纳来证明递归算法。对于某些问题,例如递归斐波那契,这种模式以一种明显的方式出现。我的问题是,比如说,二叉树遍历是否也可以被视为遵循这种模式?
以深度优先搜索为例:
def DFS(root):
if root == None:
return
print(root.value)
DFS(root.left)
DFS(root.right)
我了解代码和调用堆栈,但我很难准确地阐明 DFS 的第 1 步和第 2 步是什么(保持上述递归解决方案的结构)。不可能只有当当前节点为None时才是base case,因为遍历单个节点也应该是base case。
如果我说第 4 行,即包含 print 语句的那一行,是一个基本情况,它没有多大意义,因为它针对每个子树运行。
【问题讨论】:
-
如果我没记错的话,这看起来更像是预购遍历而不是 DFS……?无论如何,单个节点如何成为基本案例?只有
root == None是所示算法中的基本情况。这里有一个(叶)节点,您仍然可以递归并访问它的子节点,即使它们是None。试图对此应用归纳似乎有点想多了。我不确定它到底能带来什么好处。 -
@ggorlen 没错,这只是没有搜索的预购遍历。对我来说,这样做的好处是将两个概念联系在一起并获得更深入的理解。此外,有时在思考“这个问题的最简单版本是什么?”和“我将如何从一个小问题的解决方案到一个更大的问题”有助于设计算法......我觉得我不能将这些步骤应用于树遍历问题,所以我倾向于与他们斗争。
-
对,但在这种情况下,本身并没有真正需要解决的问题——所发生的只是打印,因此没有结果或数据在树中移动。如果它们存在,您只需访问节点,打印,这就是它的全部内容。像这样的基本树遍历中唯一的“技巧”/“洞察力”是打印(或通用访问代码)去哪里产生不同的排序?
标签: recursion tree binary-search-tree tree-traversal induction