Algorithm 递归模式的大O时间复杂度
我对递归模式的运行时有疑问 示例1Algorithm 递归模式的大O时间复杂度,algorithm,recursion,time-complexity,big-o,Algorithm,Recursion,Time Complexity,Big O,我对递归模式的运行时有疑问 示例1 int f(int n) { if(n <= 1) { return 1; } return f(n - 1) + f(n - 1); } 我读到上面代码的运行时是O(2^logn),因为它是平衡的,但我仍然认为它是O(2^N)。有人能解释一下吗 当元素的数量每次减半时,运行时是logn。但是二叉树在这里是如何工作的呢 它是2^logn,仅仅因为它是平衡的吗 如果不平衡怎么办 编辑: 我们可以解O(2^logn)=O(N),但我认
int f(int n) {
if(n <= 1) {
return 1;
}
return f(n - 1) + f(n - 1);
}
我读到上面代码的运行时是O(2^logn),因为它是平衡的,但我仍然认为它是O(2^N)。有人能解释一下吗
谢谢 我要试试看 在平衡二叉树中,每个父节点的左侧和右侧各有一半子节点。树的第一层是根,有1个元素,下一层有2个元素,下一层有4个元素,然后是8个元素,依此类推。因此,对于具有L层的树,树中有
2^L-1
节点
与此相反,如果您有N个元素要插入到树中,那么最终将得到一个深度为L=log_2(N)
的平衡二叉树,因此您只需要调用log_2(N)
层的递归算法。在每一层中,对算法的调用数量都是原来的两倍,因此在您的情况下,您最终会得到2^log\u 2(N)
调用和O(2^log\u 2(N))
运行时。请注意,2^log_2(N)=N
,因此这两种方法都是相同的,但我们将在一秒钟内利用二叉树的优势
如果树不平衡,则最终深度大于log_2(N)
,因此有更多的递归调用。在极端情况下,当您的所有子对象都位于其父对象的左侧(或右侧)时,您有N个递归调用,但每个调用都会立即从其一个分支返回(一侧没有子对象)。因此,您将有O(N)
运行时,这与以前相同。每个节点访问一次
平衡树的一个优点是在类似搜索的情况下。如果左边的子节点总是小于父节点,而右边的子节点总是大于,则可以在O(log_2(n))
time(而不是2^log_2(n)
)中的n
节点中搜索元素n
)。但是,如果您的树严重不平衡,则此搜索将成为所有值的线性遍历,并且您的搜索是O(N)
。如果N
非常大,或者您执行了大量的搜索,这可能是易处理算法和难处理算法之间的区别。- 二叉树与这里的任何其他树一样具有复杂性
,因为您最终要遍历树的所有元素。通过减半,我们没有做任何特殊的事情,除了分别计算相应孩子的总和O(n)
- 这个术语是这样来的,因为如果它是平衡的,那么
是树中元素的数量(叶+非叶)。(2^(log_2(n))
levels)log2(n)
- 同样,如果它不平衡,那也没关系。我们正在做一个需要考虑每个元素的操作,使运行时成为
O(n)
这在哪里有意义?如果它正在搜索一个元素,那么它就很重要(不管它是否平衡) 只是澄清一下:2^(logn)与N是相同的,所以O(2^ logn)可能与O(N)是相同的。这个特殊的函数是O(N),无论它是否平衡,因为如果不访问所有N个节点来读取所有N个值,就无法对所有N个值求和。在这个问题中,不管你是否使用二叉树,你都要访问每个节点一次,所以你的复杂度是O(N)。它是O(2^N),其中N是深度。它是O(2^logn),其中N是节点数。N是一个变量,问题中没有N,因此可以假设它是任何东西-可能任何人告诉你它是O(2^N)只是做出了一个与你不同的假设(或者可能他们只是错了)。这个
sum
函数不是O(2^logn)
–它是O(N)
谢谢你的解释:)
int sum(Node node) {
if(node == null) {
return 0;
}
return sum(node.left) + node.value + sum(node.right);
}