对于二进制搜索树类型的数据结构,我看到Big O标记通常记为O(logn)。 如果日志中的字母为小写" l",这是否意味着以自然对数描述的对数e(n)为对数? 很抱歉这个简单的问题,但是我一直很难区分不同的隐式对数。
-
正如其他人坚定地指出的那样,这无关紧要。所有对数彼此之间只有一个常数,仅取决于所涉及的底数。由于这些因素是常数,因此对于渐进分析而言,它们是无关紧要的。其次,就隐含基础的确定而言,它取决于上下文。作为粗略的经验法则,请使用以下内容:1.数学家写log n时,他表示自然对数。 2.当计算机科学家写log n时,他的意思是基数2。 3.当工程师写log n时,他的意思是十进制。这些通常是正确的。
-
@Jason,另一项约定(在数学范围内)是ln n表示自然对数,log n以10为底。 Think ln代表法国对数naturelle。
-
对数的底数是每个节点具有的子代数。如果是二叉树,则以2为底的对数。
-
杰森,感谢您的回答,还有一些需要考虑的问题。当我研究了日志的基础时(我假设为2),我看到了相同的答案:没关系,因为您可以消除常数log_10(2)。我的问题是,例如:5 log_10(5)<5而5 log_2(5)>5。我在计算中快速输入了这些内容,以帮助概念化O(n logn)的运行时间比O更好或更差的地方(n)。取决于基础,这很重要。因此,我真的认为正确的答案应该是在大多数计算机科学应用程序中上下文相关的日志表示以2为基数。
-
@ jason,Id表示它更易于使用ln(数学??家的解释);)。另外两个例子是合理的。
-
@DougMead 5是一个很小的值。总是为n> c(某个常数)定义复杂度。因此,替换一个足够大的值并进行检查。.在您的情况下,对于所有n> c,您将始终看到O(nlog_c n)> O(n)。现在,您可以决定什么是基数,此等式将始终为真。 :)
-
啊啊,我希望没人能注意到我的评论:P我很快就发现了这一点,但是感谢11个月后给我一些当之无愧的尴尬,哈哈哈
-
渐进符号仅用于表示上限和下限,而不是精确的计算数量。再过两年后怎么样? :D
大O表示法不受对数底数的影响,因为不同底数中的所有对数均与常数因子相关,O(ln n)等于O(log n)。
-
漂亮的图形15
-
图形很整洁,但请考虑O()多项式的推导...在应用O()之前,只有对数为2的二进制搜索才正确。
-
@Heath Hunnicutt:编号log_2 x与log_b x的区别在于,对于任何独立于x的基本b,常数c(b)。
-
杰森-您误读了"在应用O()之前"。另请参阅以下我的答案。 Cade对于O()表示法当然是正确的。但是,我正在谈论前O()表示法的推导,我的建议是,存在人类理解的原因,而不是数学原因,一旦您将O_2转换为O(, )。
-
但是,当它与问题无关而只会造成混淆时,您为什么要谈论它呢?
-
我认为希思(Heath)提出了一个有用的观点,相对于n的增长起源与log 2 sub>有关。
-
霍布斯:因为那是OP激发询问的原因。我试图将自己的想法与答案联系起来,因此他理解了为什么有直觉,为什么直觉不适用于O(),但又不将他在这里学到的知识过度应用到分析的推导部分。简短的答案不能解决误解的根本原因,可能会导致进一步的误解。它的教学法很差。
-
@ Heath Hunnicutt:但是重点是没关系。
-
Jason:毫无意义是要帮助OP理解。而且,在导致O()的推导的每一行上,它确实很重要。只要在O()中重新表达一次就没有关系。许多其他读者也明白这一点。而且您知道我知道O(log N)= O(ln N),对吗?
-
@Heath Hunnicutt:如果您要进行渐近分析,那没关系。等到最后一分钟扔一些大O并不会改变我可以将所有对数乘以一个愚蠢的常数并在所有步骤都改变底数这一事实。也就是说,如果我进行了涉及log_2 n的分析,那么我可以直接将所有log_2 n替换为log_pi 2 * log_2 n log_pi 2,然后最后得到一个到处都有log_pi 2 * log_pi n的分析。现在,我的分析是基于log_pi n的。
-
@jason显然我知道这一点。您缺少的是对数底数在推导O()表达式中的相关性。您没有注意大多数步骤,只有最后一步。您认为无关的区别实际上与理解推导非常相关。这样,围绕O()表示法和股票面试答案的教条会使您退缩。缺点是在推导过程中不了解对数底的相关性。
一旦用big-O()表示法,两者都是正确的。但是,在O()多项式推导过程中,对于二进制搜索,只有log 2 sub>是正确的。我认为这种区别是您提出问题的直观灵感。
另外,根据我的观点,写O(log 2 sub> N)对于您的示例更好,因为它可以更好地传达算法运行时间的推导。
在big-O()表示法中,常数因子被删除。从一个对数底数转换为另一对数底数需要乘以一个常数因子。
因此,由于常数因子,O(log N)等于O(log 2 sub> N)。
但是,如果您可以轻松地在答案中输入log 2 sub> N,则这样做更具教学意义。在二叉树搜索的情况下,正确的是在导出big-O()运行时期间引入了log 2 sub> N。
在将结果表示为big-O()表示法之前,区别非常重要。当推导要通过big-O表示法传递的多项式时,在此示例中,在应用O()表示法之前使用log 2 sub> N以外的对数是不正确的。一旦使用了多项式通过big-O()表示法来传达最坏情况的运行时,使用什么对数就无关紧要了。
-
但是很容易显示log_2 n在任何基数a中的Θ(log_a n)中,所以我不确定我知道使用基数2是"更正确的"方法。
-
抱歉,"轻松排版"是什么意思?
-
在回答的第一句话中。
-
Kinopiko-例如,如果您手工写下来。但是,我认为O(N log N)比O(N log-base-2 N)更具可读性,但是如果我使用的是TeX,即使在O()内部,我也肯定会写$ log_2 $只是为了使指出O()来自具有$ log_2 $而不是$ log $的多项式。明白了吗?
-
我看到了bcat。好吧,我希望您能阅读其余的答案,并明白我的意思。您还可以在同一句话中看到我写的"都是正确的"。我将其更改为"更好",因为那更加敏锐。
-
我明白你的意思,尽管措辞有点奇怪。
-
bcat-想象您正在导出二进制搜索运行时的多项式,然后再以O()或Theta()表示法编写它……只有log-base-2是正确的。我同意,一旦将其表示为O(),便可以将其重新表示为任何基数。但是由于用于推导的多项式与任何其他对数都是错误的...我们忘记了在表达O()之前,需要派生运行时的多项式表达式。对于二进制搜索之类的事情,我们很久以前就已经做了多项式,因此我们忘记了它,只记得O()答案。
-
哦,我明白你在说什么。那讲得通。
-
+1我认为这是一个有用的解释。
-
Kinopkio和bcat,感谢您帮助它变得有用。起初它写得不是很好。 :)
-
在推导过程中log_2是正确的并不正确。可能是正确的(例如,二进制搜索),但没有先验的理由相信会是这种情况。 log_3甚至log_e自然显示存在很多问题。
-
但是这个问题是关于二进制搜索的,所以实际上是真的。
-
顺便说一句,我只是想澄清一下,我的上述回答是因为问题的标题是" Big O(logn)log base e?",并且答案似乎总体上都在解决这个问题,而不是专门针对二进制搜索。恐怕您的解释可能会使人们感到困惑。如果您很清楚地表明您只在谈论二进制搜索,那很好。
-
好吧,我增加了清晰度,但是我相信您可能会误以为我的回答会让您感到困惑。实际上,这里的大多数答案都没有考虑到OP的直觉,而是试图教给他很多东西。我并没有被比赛吓到,我对教学法的低标准感到难过。
-
这里有很多好的答案,很难选择最终答案。 Big-O表示法的基数无关紧要的事实回答了我的模棱两可的问题(答案无处不在)。这个答案还提供了二进制搜索树的O表示法前推导,这是我可能被误导的问题的初衷。谢谢您的帮助。
-
不错的选择15ch
-
谢谢BuckFilledPlatypus,衷心感谢您的评论和选择。
-
"在推导O()多项式的过程中,对于二进制搜索,只有log2是正确的。" -1用于较差的数学。 x(n)?O(f(n))的定义表示存在一个常数c,使得对于所有n> n_0,c *(f(n))
-
rlbond:那是小事。您可以在这里阅读许多其他评论,并意识到我了解您的意思,并且不同意您的教学法。在OP验证答案后,将结果设为-1(这在数学上不会与您不同)肯定是一件令人激动的事情。
-
@Kinopiko-"轻松排版"表示如果您无法在编辑器中轻松键入下标,则它更易于编写log()(就像本例一样)
-
这些评论太长了。
-
我认为您的回答有误导性。我给它一个-1,因为我觉得它应该得到-1。如果有人不同意您的答案,请不要将其视为个人,它仍然是最重要的,而且仅仅是社区Wiki!并且,一旦OP接受答案,就不会再有任何问题了。社区仍然有责任判断每个答案的适用性,以便其他人可以访问信息。
-
搜索(完全不平衡)二叉树的最坏情况运行时为O(n),搜索平衡二叉树的最坏情况运行时为O(log n)。
-
@rlbond-尽管您的哲学可能是正确的,但您对我的数学的评论是错误的。在推导过程中,对数以2为底,仅在此之后无关紧要。我的陈述在数学上不是错误的,而是您的建议是正确的。
-
由于log2(x)等于log10(x)/ log10(2),因此您可以采用任何一种方式导出它。日志在任何时候都不严格是2的基数。
-
您意识到在推导过程中,我的意思是在应用O()表示法之前推导运行时多项式?在推导应用O()表示法的函数时,如果树是二叉树,对数也是。
它的基础是什么都没有关系,因为通常写出大O表示仅显示n的渐近最高阶,因此常数系数将消失。由于不同的对数基数等于常数系数,因此它是多余的。
话虽如此,我可能会假设对数为2。
-
-1错了。
-
@Kinopiko:这到底是什么问题?更确切地说,我的回答实际上与您和此处的其他人有何不同?
-
嗯,也许是我在使用"系数"时出错了。我将进行澄清。
-
那是我的主要问题。另外,您还不清楚"它们仍然会产生一些作用"的意思。对什么有什么影响?
-
您的答案讨论了最高阶系数。您所说的话就目前而言是正确的,但这并不是对数底数无关紧要的原因。原因是不同基本对数之间的差是一个常量,可以由O()吸收。
-
这仍然不是真的正确,在这种情况下,谈论n的最高阶没有任何意义。 Cade Rouxs的答案是正确的。
-
@Kinopiko:...,并且常量被O()"吸收",因为我们只关心n的最高阶系数。对?
-
也许我误会了一些东西。 O(f(n))的定义是否是表示算法渐近复杂度的函数f()作为n的函数?渐进复杂度由表达式的高阶部分决定,因此,低阶(或常数)表达式是多余的。还是我误解了一些基本知识?
-
@Daniel:因为例如O(100)= O(1),所以没有吸收常数C。
-
@Kinopiko:好的。我想我们在说同样的话。我会说O(100)= O(1)是因为O(100)= O(100 * 1)= O(C * 1)= O(1)。我的意思是常量表达式是多余的。也就是说,任何常数的阶数均为1。
两者都是正确的。考虑一下
1 2 3
| log2(n)=log(n)/log(2)=O(log(n))
log10(n)=log(n)/log(10)=O(log(n))
logE(n)=log(n)/log(E)=O(log(n)) |
首先,您必须了解函数f(n)为O(g(n))的含义。
形式上的定义是:*一个函数f(n)被称为O(g(n))iff | f(n)| <= C * | g(n)|每当n> k时,其中C和k为常数。
因此,令f(n)= n的对数a,其中a> 1,而g(n)= n的对数b,其中b> 1
注意:这意味着值a和b可以是大于1的任何值,例如a = 100和b = 3
现在我们得到以下结果:n的对数底数a被称为O(n的对数底数b)iff | n |的对数底数a | <= C * |以n为底的对数b |每当n> k
选择k = 0,并且C =以b为底的对数。
现在我们的方程式如下:| n的对数底| <= b的对数底数a * | n的对数底数b |每当n> 0
注意右侧,我们可以处理以下等式:= b的对数底数a * | n |的对数底数b = |以n为底的对数b | * b的对数基数a = | b ^的对数基数a(n的对数基数b)| = |以n为底的对数a |
现在我们的方程式如下:| n的对数底| <= | n的对数基数a |每当n> 0
除了其约束a,b> 1和n> 0之外,无论值n,b或a是多少,该方程始终是正确的。
因此,n的对数底数a为O(n的对数底数b),由于a,b无关紧要,我们可以简单地忽略它们。
您可以在此处查看YouTube视频:https://www.youtube.com/watch?v=MY-VCrQCaVw
您可以在此处阅读有关此文章:https://medium.com/@randerson112358/omitting-bases-in-logs-in-big-o-a619a46740ca
是的,在谈论big-O表示法时,基数无关紧要。但是,在计算上,当遇到真正的搜索问题时,它确实很重要。
在开发有关树结构的直觉时,了解可以在O(n log n)时间内搜索二叉搜索树很有帮助,因为这是树的高度-也就是说,在具有n个节点的二叉树中,树深度为O(n log n)(以2为底)。如果每个节点有三个子节点,仍然可以在O(n log n)时间内搜索树,但对数为3。通过计算,每个节点具有的子代数可能会对性能产生很大影响(例如,请参见链接文本)
请享用!
保罗
-
您的意思是说二叉树的高度是log n,而不是n log n,对吗?
从技术上讲,基数并不重要,但是您通常可以将其视为基数2。