以下递归算法的运行时间?

时间:2016-10-19 19:38:44

标签: algorithm recursion binary-search-tree

我正在阅读这本书"破解编码面试"通过Gayle McDowell发现了一个有趣的递归算法,该算法对平衡二叉搜索树中所有节点的值进行求和。

int sum(Node node) {
 if (node == null) {
  return 0;
 }
 return sum(node.left) + node.value + sum(node.right);
}

现在Gayle说运行时是O(N)我觉得很困惑,因为我不知道这个算法将如何终止。对于给定节点,当node.left在第一次调用中传递给sum,然后node.right因此在第二次调用中传递给sum时,不是算法第二次计算sum(节点) ?这个过程不会永远持续下去吗?我还不熟悉递归算法,所以它可能不是很直观。

干杯!

2 个答案:

答案 0 :(得分:1)

这个过程不会永远持续下去。有问题的数据结构是平衡二进制搜索树,而不是可以包含循环的图。

从root开始,所有节点都将以left -> itself -> right的方式进行探索,就像深度优先搜索一样。

node.left将探索节点的左子树,node.right将探索同一节点的右子树。两个子树都没有交叉。绘制程序控制的轨迹以查看探索节点的顺序,并查看遍历中没有重叠。

由于每个节点只被访问一次,并且当一个叶节点被命中时递归将开始展开,运行时间将是O(N),N是节点数。< / p>

答案 1 :(得分:-1)

理解递归算法的关键是相信它能够做到它所认为的那样。让我解释一下。

首先承认函数sum(node)返回以node为根的子树的所有节点的值的总和。

然后是代码

 if (node == null) {
  return 0;
 }
 return sum(node.left) + node.value + sum(node.right);

可以做两件事:

  1. 如果节点为null,则返回0;这是一个非递归的情况,返回的值非常正确;

  2. 否则,函数会计算左子树的总和加上node的值加上右子树的总和,即根据node生成的子树的总和。

  3. 所以在某种程度上,如果函数是正确的,那么它是正确的:)实际上,由于非递归的情况,这个论证不是循环的,这也是正确的。

    我们可以使用相同的推理方式来证明算法的运行时间。

    假设处理以节点为根的树所需的时间与此子树的大小成比例,请|T|。这是另一种信仰行为。

    如果node为空,则时间是常数,让1为单位。如果node不为空,则时间为|L| + 1 + |R|个单位,正好是|T|。因此,如果对子树求和的时间与子树的大小成正比,那么求和树的时间与树的大小成正比!