我正在学习Big O Notation运行时间和摊销时间。 我理解O(n)线性时间的概念,意味着输入的大小成比例地影响算法的增长...例如,二次时间O(n 2 )等也是如此。即使算法也是如此。 ,例如置换生成器,具有O(n!)倍,通过阶乘生长。
例如,以下函数是O(n),因为算法与其输入n成比例增长:
f(int n) {
int i;
for (i = 0; i < n; ++i)
printf("%d", i);
}
同样,如果有嵌套循环,则时间为O(n 2 )。
但究竟什么是O(log n) ? 例如,说完整二叉树的高度是O(log n)是什么意思?
我知道(可能不是非常详细)什么是对数,在这个意义上:log 10 100 = 2,但我无法理解如何识别具有对数时间的函数。
#1楼
下面的解释是使用完全平衡的二叉树的情况来帮助您了解我们如何获得对数时间复杂度。
二叉树是这样一种情况,其中大小为n的问题被分成大小为n / 2的子问题,直到我们达到大小为1的问题:
这就是你得到O(log n)的方法,这是在上面的树上需要完成的工作量才能达到解决方案。
具有O(log n)时间复杂度的通用算法是二进制搜索,其递归关系是T(n / 2)+ O(1),即在树的每个后续级别,您将问题分成一半并且执行恒定量的额外工作。
#2楼
但究竟什么是O(log n)? 例如,说>完整二叉树的高度是O(log n)是什么意思?
我将其改为'完整二叉树的高度为log n'。 如果您逐步向下遍历,则确定完整二叉树的高度将为O(log n)。
我无法理解如何识别具有对数时间的函数。
对数基本上是取幂的倒数。 因此,如果函数的每个“步骤”都消除了原始项集中的元素因子 ,那么这就是对数时间算法。
对于树示例,您可以轻松地看到,当您继续遍历时,降低节点级别会减少指数数量的元素。 查看名称排序电话簿的流行示例基本上等同于遍历二叉搜索树(中间页面是根元素,您可以在每个步骤推断出是向左还是向右)。
#3楼
如果您正在寻找基于直觉的答案,我想为您提出两种解释。
想象一座非常高的山丘,也有非常宽阔的底座。 到达山顶有两种方式:一种是围绕山顶螺旋形地穿过顶部的专用通道,另一种是用于雕刻的小露台,以提供楼梯。 现在,如果第一种方式达到线性时间O(n),则第二种方式是O(log n)。
想象一个算法,它接受一个整数,
n
作为输入并在时间上与n
成比例地完成,然后它是O(n)或theta(n)但是如果它在时间上与number of digits or the number of bits in the binary representation on number
比例运行number of digits or the number of bits in the binary representation on number
然后算法在O(log n)或theta(log n)时间运行。
#4楼
log x to base b = y
是b^y = x
的倒数
如果你有一个深度为d且大小为n的M-ary树,那么:
遍历整棵树~O(M ^ d)= O(n)
在树中走一条路径~O(d)= O(log n到基数M)
#5楼
这两种情况需要O(log n)时间
case 1: f(int n) {
int i;
for (i = 1; i < n; i=i*2)
printf("%d", i);
}
case 2 : f(int n) {
int i;
for (i = n; i>=1 ; i=i/2)
printf("%d", i);
}