我更喜欢尽可能少的正式定义和简单的数学。
答案 0 :(得分:6374)
答案 1 :(得分:695)
它显示了算法如何扩展。
O(n 2 ):称为二次复杂度
请注意,项目数量增加了10倍,但时间增加了10倍 2 。基本上,n = 10,因此O(n 2 )给出了比例因子n 2 ,即10 2 。
O(n):称为线性复杂性
这次项目数量增加了10倍,时间也增加了10倍。 n = 10,所以O(n)的比例因子是10。
O(1):称为常量复杂性
项目数仍然增加10倍,但O(1)的比例因子始终为1.
O(log n):称为对数复杂度
计算次数仅增加输入值的对数。所以在这种情况下,假设每次计算需要1秒,输入n
的日志就是所需的时间,因此log n
。
这就是它的要点。他们减少了数学,所以它可能不完全是n 2 或者它们所说的,但这将是缩放的主要因素。
答案 2 :(得分:381)
答案 3 :(得分:240)
编辑:快速注意,这几乎肯定会混淆Big O notation(这是一个上限)与Theta表示法(它是一个上限和下限)。根据我的经验,这实际上是非学术环境中的典型讨论。对由此引起的任何混乱道歉。
用一句话说:随着工作规模的增加,完成工作需要多长时间?
显然,只使用“size”作为输入,“time time”作为输出 - 如果你想谈论内存使用等,同样的想法也适用。
这是一个我们想要干燥的N T恤的例子。我们假设让它们处于干燥位置非常快(即人类的相互作用可以忽略不计)。现实情况并非如此,当然......
在外面使用清洗线:假设您有一个无限大的后院,洗涤在O(1)时间内干燥。无论你有多少,它都会得到相同的阳光和新鲜空气,所以尺寸不会影响干燥时间。
使用滚筒式烘干机:每次装入10件衬衫,然后一小时后完成。 (忽略这里的实际数字 - 它们无关紧要。)因此,干燥50件衬衫需要约干燥10件衬衫的次数。
把所有东西都放在一个通风橱里:如果我们把所有东西放在一个大堆里,只要让一般温暖,那么中间衬衫要干燥需要很长时间。我不想猜测细节,但我怀疑这至少是O(N ^ 2) - 随着你增加洗涤负荷,干燥时间增加得更快。
“大O”符号的一个重要方面是它不说哪个算法对于给定的大小会更快。获取哈希表(字符串键,整数值)与对数组(字符串,整数)。基于字符串,在哈希表或数组中的元素中查找键是否更快? (即对于数组,“找到字符串部分与给定键匹配的第一个元素。”)哈希表通常是摊销的(〜=“平均”)O(1) - 一旦它们被设置,它应该采取同时在100条目表中查找条目,如1,000,000条目表中所示。在数组中查找元素(基于内容而不是索引)是线性的,即O(N) - 平均而言,您将不得不查看一半的条目。
这是否使哈希表比查找数组更快?不必要。如果你有一个非常小的条目集合,一个数组可能会更快 - 你可以在计算你正在查看的哈希码的时间内检查所有字符串。然而,随着数据集变大,哈希表最终会击败数组。
答案 4 :(得分:122)
Big O描述了函数增长行为的上限,例如当输入变大时函数的运行时。
示例:
O(n):如果我将输入大小加倍,则运行时间加倍
O(n 2 ):如果输入大小是运行时四倍的两倍
O(log n):如果输入大小加倍,则运行时间增加一个
O(2 n ):如果输入大小增加1,则运行时间加倍
输入大小通常是表示输入所需的位数。
答案 5 :(得分:101)
程序员最常使用Big O表示法作为计算(算法)完成所需时间的近似度量,表示为输入集大小的函数。
Big O可用于比较两种算法随着输入数量的增加而扩展的程度。
更精确地Big O notation用于表示函数的渐近行为。这意味着函数在接近无穷大时的行为方式。
在许多情况下,算法的“O”将属于下列情况之一:
当输入大小朝向无穷大增加时,大O忽略了对函数的增长曲线没有有意义贡献的因素。这意味着简单地忽略了添加到函数或乘以函数的常量。
答案 6 :(得分:78)
Big O只是一种以一种常见方式“表达”自己的方式,“运行我的代码需要多长时间/空间?”。
你可能经常看到O(n),O(n 2 ),O(nlogn)等等,所有这些只是展示的方式;算法如何改变?
O(n)意味着大O是n,现在你可能会想,“什么是n!?” “n”是元素的数量。想要在阵列中搜索项目的图像。您必须查看每个元素并将其视为“您是正确的元素/项目吗?”在最坏的情况下,该项目位于最后一个索引,这意味着它花费的时间与列表中的项目一样多,因此为了通用,我们说“哦,嘿,n是一个公平的给定数量的值!”
那么你可能会理解“n 2 ”意味着什么,但更具体地说,你可以想到你有一个简单,最简单的排序算法;冒泡。该算法需要查看每个项目的整个列表。
我的清单
这里的流程将是:
这是O n 2 因为,您需要查看列表中的所有项目都有“n”项。对于每个项目,您再次查看所有项目,为了进行比较,这也是“n”,因此对于每个项目,您看起来都是“n”次,意味着n * n = n 2
我希望这就像你想要的一样简单。
但请记住,Big O只是一种以时间和空间的方式超越自我的方式。
答案 7 :(得分:53)
Big O描述了算法的基本缩放特性。
Big O没有告诉你有关给定算法的大量信息。它切入骨骼并仅提供有关算法的缩放特性的信息,特别是算法的资源使用(思考时间或内存)如何根据“输入大小”进行缩放。
考虑蒸汽机和火箭之间的区别。它们不仅仅是同一种物品的不同品种(例如,普锐斯发动机与兰博基尼发动机),但它们的核心是不同类型的推进系统。蒸汽机可能比玩具火箭更快,但没有蒸汽活塞发动机能够达到轨道运载火箭的速度。这是因为这些系统在达到给定速度(“输入尺寸”)所需的燃料关系(“资源使用”)方面具有不同的缩放特性。
为什么这么重要?因为软件处理的问题可能因数据大小不同而有所不同。考虑一下。前往月球所需的速度与人类行走速度之间的比率小于10,000:1,与软件可能面临的输入尺寸范围相比,这是非常小的。而且由于软件可能面临输入大小的天文范围,因此算法的Big O复杂性可能会超越任何实现细节,这是基本的扩展性质。
考虑规范排序示例。冒泡排序为O(n 2 ),而merge-sort为O(n log n)。假设您有两个排序应用程序,即使用冒泡排序的应用程序A和使用合并排序的应用程序B,并且假设对于大约30个元素的输入大小,应用程序A在排序时比应用程序B快1,000倍。如果您不必排序超过30个元素,那么您应该更喜欢应用程序A,因为它在这些输入大小上要快得多。但是,如果您发现可能需要对一千万个项目进行排序,那么您所期望的是,在这种情况下,应用程序B实际上最终比应用程序A快数千倍,这完全取决于每种算法的扩展方式。
答案 8 :(得分:37)
这是我在解释Big-O的常见变种时倾向于使用的普通英语动物
在所有情况下,首选列表中较高的算法列表中较低的算法。但是,迁移到更昂贵的复杂性类别的成本差异很大。
<强> O(1):强>
没有增长。无论问题有多大,您都可以在相同的时间内解决问题。这有点类似于广播,无论广播范围内的人数是多少,广播都需要相同的能量才能在给定距离内广播。
O(log n ):
这种复杂性与 O(1)相同,只是它稍微差一点。出于所有实际目的,您可以将其视为非常大的常量缩放。处理1千到10亿件物品之间的工作差异只有6倍。
<强> O(名词的):强>
解决问题的成本与问题的大小成正比。如果您的问题规模增加一倍,那么解决方案的成本会翻倍。由于大多数问题必须以某种方式扫描到计算机中,如数据录入,磁盘读取或网络流量,这通常是一个负担得起的缩放因子。
O( n log n ):
此复杂性与 O( n )非常相似。出于所有实际目的,这两者是等价的。这种复杂程度通常仍被认为是可扩展的。通过调整假设,一些 O( n log n )算法可以转换为 O( n ) 算法。例如,限制键的大小会减少从 O( n log n )到 O( n )强>
<强> O(名词 2 ):强>
生长为正方形,其中 n 是正方形边长。这与“网络效应”的增长率相同,网络中的每个人都可能知道网络中的其他人。增长是昂贵的。大多数可扩展的解决方案不能使用具有这种复杂程度的算法,而无需进行重要的体操。这通常适用于所有其他多项式复杂度 - O( n k ) - 以及。
<强> O(2 名词 ):强>
不缩放。你没有希望解决任何非平凡的问题。用于了解要避免的内容,以及专家找到 O( n k )中的近似算法。
答案 9 :(得分:35)
Big O衡量算法使用的时间/空间相对于其输入的大小。
如果算法为O(n),则时间/空间将以与输入相同的速率增加。
如果算法为O(n 2 ),则时间/空间以其输入平方的速率增加。
等等。
答案 10 :(得分:31)
测量软件程序的速度非常困难,当我们尝试时,答案可能非常复杂,并且充满异常和特殊情况。这是一个大问题,因为当我们想要将两个不同的程序相互比较以找出哪个是“最快的”时,所有这些异常和特殊情况都会分散注意力并且无益。
由于所有这些无用的复杂性,人们试图用尽可能最小和最不复杂(数学)的表达来描述软件程序的速度。这些表达式是非常粗略的近似值:虽然运气不错,但它们将捕捉到软件是快还是慢的“本质”。
因为它们是近似值,所以我们在表达式中使用字母“O”(Big Oh),作为一种惯例向读者发出信号,表明我们正在进行粗略的过度简化。 (并确保没有人错误地认为表达方式是准确的)。
如果您将“Oh”视为“大约”或“大约”的意思,那么您就不会走得太远。 (我认为Big-Oh的选择可能是幽默的尝试。)
这些“Big-Oh”表达式尝试做的唯一事情就是描述软件在增加软件必须处理的数据量时减慢了多少。如果我们将需要处理的数据量增加一倍,那么软件需要两倍的时间才能完成它的工作吗?十倍的时间?在实践中,你会遇到并且需要担心的大哦表达的数量非常有限:
好处:
O(1)
常量:无论输入多大,程序都会运行相同的时间。O(log n)
对数:即使输入大小大幅增加,程序运行时也只会缓慢增加。坏事:
O(n)
线性:程序运行时间与输入的大小成比例增加。O(n^k)
多项式: - 处理时间越来越快 - 作为多项式函数 - 随着输入的大小增加。......丑陋的:
O(k^n)
指数程序运行时间增加得非常快,问题的大小也会适度增加 - 使用指数算法处理小型数据集是切实可行的。O(n!)
因子除了最小和最琐碎的数据集之外,程序运行时间将比您能够等待的时间长。答案 11 :(得分:31)
Big O的简单英语解释是什么?尽可能少的正式定义和简单的数学。
Big-O表示法的需要的简明英语解释:
当我们编程时,我们正试图解决问题。我们编码的是一种算法。 Big O表示法允许我们以标准化方式比较算法的最差情况。硬件规格随时间而变化,硬件的改进可以减少算法运行所需的时间。但是替换硬件并不意味着我们的算法随着时间的推移会更好或改进,因为我们的算法仍然相同。因此,为了让我们能够比较不同的算法,以确定一个是否更好,我们使用Big O表示法。
大O符号的简单英语解释
并非所有算法都在相同的时间内运行,并且可能会根据输入中的项目数量而有所不同,我们称之为 n 。基于此,我们考虑更糟糕的案例分析,或者 n 越来越大的运行时上限。我们必须知道 n 是什么,因为许多Big O符号都引用它。
答案 12 :(得分:27)
一个简单明了的答案可以是:
Big O表示该算法的最差可能时间/空间。该算法永远不会占用超过该限制的更多空间/时间。大O代表极端情况下的时间/空间复杂性。
答案 13 :(得分:27)
好的,我的2点。
Big-O,是程序消耗的资源的增长率,w.r.t。问题实例尺寸
资源:可能是总CPU时间,可能是最大RAM空间。默认情况下是指CPU时间。
说问题是“找到总和”,
int Sum(int*arr,int size){
int sum=0;
while(size-->0)
sum+=arr[size];
return sum;
}
problem-instance = {5,10,15} ==&gt; problem-instance-size = 3,iterations-in-loop = 3
problem-instance = {5,10,15,20,25} ==&gt; problem-instance-size = 5次迭代循环= 5
对于大小为“n”的输入,程序以阵列中“n”次迭代的速度增长。因此,Big-O是N,表示为O(n)
说问题是“找到组合”,
void Combination(int*arr,int size)
{ int outer=size,inner=size;
while(outer -->0) {
inner=size;
while(inner -->0)
cout<<arr[outer]<<"-"<<arr[inner]<<endl;
}
}
problem-instance = {5,10,15} ==&gt; problem-instance-size = 3,total-iterations = 3 * 3 = 9
problem-instance = {5,10,15,20,25} ==&gt; problem-instance-size = 5,total-iterations = 5 * 5 = 25
对于大小为“n”的输入,程序以阵列中“n * n”次迭代的速度增长。因此,Big-O是N 2 ,表示为O(n 2 )
答案 14 :(得分:24)
Big O表示法是一种根据空间或运行时间来描述算法上限的方法。 n是问题中元素的数量(即数组的大小,树中的节点数等)。我们有兴趣描述n变大的运行时间。
当我们说某些算法是O(f(n))时,我们说该算法的运行时间(或所需空间)总是低于某些常数f(n)。
要说二进制搜索的运行时间为O(logn),就是说存在一些常量c,你可以将log(n)乘以它常常大于二进制搜索的运行时间。在这种情况下,您将始终有一些log(n)比较的常数因子。
换句话说,g(n)是算法的运行时间,我们说当g(n)&lt; = c * f(n)时,g(n)= O(f(n)) &GT; k,其中c和k是一些常数。
答案 15 :(得分:22)
“ Big O的简单英语解释是什么? 定义尽可能简单的数学。“
这样一个非常简单和简短的问题似乎至少应该得到一个同样简短的答案,就像学生在辅导期间可能得到的那样。
Big O表示法只是告诉算法可以运行多少时间, 就而言只有输入数据量 **。
(*精彩,无单位时间感!)
(**这是重要的,因为人们会always want more,无论他们今天或明天都住在哪里)
嗯,如果这就是Big O符号那么精彩呢?
实际上,Big O分析非常有用且重要因为Big O将重点放在算法的自己的复杂性上,完全忽略< / em>任何只是比例常数的东西 - 比如JavaScript引擎,CPU的速度,你的互联网连接,以及所有那些很快变得像模型 T 一样过时的过时的东西。 Big O只关注与现在或将来生活中的人们同等重要的表现。
Big O符号也直接关注计算机编程/工程这一最重要的原则,这一事实激发了所有优秀的程序员不断思考和梦想:实现超越漫长前进的结果的唯一途径技术是发明一种更好的算法。
答案 16 :(得分:20)
算法示例(Java):
// given a list of integers L, and an integer K
public boolean simple_search(List<Integer> L, Integer K)
{
// for each integer i in list L
for (Integer i : L)
{
// if i is equal to K
if (i == K)
{
return true;
}
}
return false;
}
算法说明:
此算法逐项搜索列表,查找密钥
对列表中的每个项目进行迭代,如果是键,则返回True,
如果循环已完成但未找到密钥,则返回False。
Big-O表示法代表复杂性的上限(时间,空间,......)
要找到Big-O on Time Complexity:
计算最坏情况需要多长时间(关于输入大小):
最坏情况:列表中不存在密钥。
时间(最坏情况)= 4n + 1
时间:O(4n + 1)= O(n)|在Big-O中,常数被忽略
O(n)~Lineal
还有Big-Omega,它代表了Best-Case的复杂性:
最佳案例:关键是第一项。
时间(最佳情况)= 4
时间:Ω(4)= O(1)~Instant \ Constant
答案 17 :(得分:18)
Big O表示法是一种描述算法在给定任意数量的输入参数下运行的速度的方法,我们将其称为“n”。它在计算机科学中很有用,因为不同的机器以不同的速度运行,并且简单地说算法需要5秒钟并不能告诉你太多,因为当你运行一个带有4.5 Ghz八核处理器的系统时,我可能正在运行一个15岁的800 Mhz系统,无论算法如何,都可能需要更长的时间。因此,我们不是指定算法在时间上运行的速度,而是根据输入参数的数量或“n”来说它运行的速度有多快。通过以这种方式描述算法,我们能够比较算法的速度,而不必考虑计算机本身的速度。
答案 18 :(得分:18)
大O
f (x)= O( g (x))当x进入a(例如,a = +∞)意味着有一个函数< em> k 这样:
f (x)= k (x) g (x)
k在某个邻域中有界(如果a = +∞,这意味着有数字N和M使得每个x> N,| k (x )|&lt; M)。
换句话说,用简单的英语: f (x)= O( g (x)),x→a,表示在a附近, f 分解为 g 和某些有界函数的乘积。
小o
顺便说一下,这里是为了比较小o的定义。
f (x)= o( g (x))当x转到a表示存在函数k时:
f (x)= k (x) g (x)
k (x)当x转到a时变为0.
实施例
当x→0时,sin x = O(x)。
sin x = O(1)当x→+∞时,
x 2 + x = O(x)当x→0时,
x 2 + x = O(x 2 ),
当x→+∞时,ln(x)= o(x)= O(x)。
注意!带有等号“=”的符号使用“假等式”:o(g(x))= O(g(x)),但是为假O(g(x))= o(g(x))。类似地,当x→+∞时写“ln(x)= o(x)是可以的,但公式”o(x)= ln(x)“没有意义。
更多示例
O(1)= O(n)= O(n 2 )当n→+∞时(但不是相反,等式是“假的”),< / p>
O(n)+ O(n 2 )= O(n 2 )当n→+∞
O(O(n 2 ))= O(n 2 )当n→+∞
O(n 2 )当n→+∞时,O(n 3 )= O(n 5 )
以下是维基百科的文章:https://en.wikipedia.org/wiki/Big_O_notation
答案 19 :(得分:11)
我不确定我是否会对这个问题做出进一步的贡献,但仍然认为我会分享:我曾经发现this blog post有一些非常有帮助的(虽然非常基本的)解释&amp; Big O的例子:
通过例子,这有助于将基本的基本部分放入我的玳瑁般的头骨中,所以我认为这是一个非常下降的10分钟阅读,让你朝着正确的方向前进。
答案 20 :(得分:11)
你想知道大O的所有知识吗?我也是。
所以谈到大O,我将使用只有一个节拍的单词。每个单词一个声音。小词很快。你知道这些话,我也一样。我们会用一个声音的单词。他们很小。我相信你会知道我们将使用的所有词语!
现在,让我们和你谈谈工作。大多数时候,我不喜欢工作。你喜欢上班吗?你可能会这样,但我相信我没有。
我不喜欢去上班。我不喜欢在工作上花时间。如果我有自己的方式,我只想玩,做有趣的事情。你觉得和我一样吗?
现在有时,我必须去上班。这很难过,但却是真的。所以,当我在工作时,我有一个规则:我尝试做更少的工作。我尽可能无法工作。然后我去玩!
所以这是个大新闻:大O可以帮助我不做工作!我可以玩更多的时间,如果我知道大O.少工作,多玩!这就是大O帮助我做的事情。
现在我有一些工作。我有这个清单:一,二,三,四,五,六。我必须在此列表中添加所有内容。
哇,我讨厌工作。但是哦,我必须这样做。所以我走了。一加二是三......加三是六......四是......我不知道。我迷路了。我脑子里很难做到这一点。我不太关心这种工作。
所以,让我们不做这项工作。让我们和你思考它有多难。我需要做多少工作才能添加六个数字?
嗯,让我们看看。我必须添加一个和两个,然后将其添加到三个,然后将其添加到四个...总而言之,我计算六个添加。我必须做六个补充来解决这个问题。这里有大O,告诉我们这个数学有多难。
Big O说:我们必须做六个补充来解决这个问题。一个补充,每个东西从一到六。六个小工作......每一项工作都是一个补充。
好吧,我现在不会去做它们的工作。但我知道它会有多难。这将是六个补充。
哦不,现在我有更多的工作。啧。谁做这种东西?!
现在他们要我加一到十!我为什么要这么做?我不想添加一到六个。从一到十加......好吧......那会更难!
它会变得多难?我还需要做多少工作?我需要更多或更少的步骤吗?
好吧,我想我必须做十次补充......一次从一到十次。十分超过六分。我需要做更多工作,从一到十,而不是一到六!
我现在不想添加。我只是想想加入那么多可能有多难。并且,我希望,尽快发挥。
要从一到六添加,这是一些工作。但是你知道,从一到十加上,这是更多的工作吗?
Big O是你的朋友和我的朋友。 Big O帮助我们思考我们需要做多少工作,所以我们可以计划。而且,如果我们是大O的朋友,他可以帮助我们选择不那么难的工作!
现在我们必须做新工作。不好了。我根本不喜欢这件事。
新工作是:将所有内容从一个添加到n。
等待!什么是n?我错过了吗?如果你不告诉我什么是n,我如何从一个添加到n?
好吧,我不知道n是什么。我没有被告知。是吗?没有?那好吧。所以我们不能做这项工作。呼。
但是,虽然我们现在不会做这项工作,但如果我们知道的话,我们可以猜到它会有多难。我们必须加起来,对吗?当然!
现在这里有大O,他会告诉我们这项工作有多难。他说:将所有东西从一个添加到N,一个接一个,是O(n)。要添加所有这些东西,[我知道我必须添加n次。] [1]那是大O!他告诉我们做某种工作有多难。
对我而言,我认为大O就像一个又大又慢的老板。他在工作上思考,但他没有这样做。他可能会说,&#34;这项工作很快。&#34;或者,他可能会说,&#34;这项工作是如此缓慢和艰难!&#34;但他不做这项工作。他只看工作,然后告诉我们可能需要多长时间。
我非常关心大O.为什么?我不喜欢上班!没有人喜欢工作。这就是为什么我们都喜欢大O!他告诉我们我们的工作速度有多快。他帮助我们思考工作是多么努力。
哦,哦,更多的工作。现在,我们不做这项工作。但是,让我们一步一步地制定计划。他们给了我们一张十张牌。他们都混在一起:七,四,二,六......根本不直。而现在......我们的工作就是对它们进行分类。
Ergh。这听起来像是很多工作!
我们怎样才能对这个套牌进行排序?我有个计划。
我将从头到尾看着每对卡片,一副一对地穿过甲板。如果一对中的第一张卡很大而且该对中的下一张卡很小,我会换掉它们。否则,我会去下一对,依此类推......很快,甲板就完成了。
当牌组完成后,我问:我是否在那张传球中换了牌?如果是这样,我必须从顶部再一次完成。
在某些时候,某个时候,将不会进行掉期交易,而且我们的甲板将会完成。这么多工作!
那么,根据这些规则对牌进行排序会有多少工作?
我有十张牌。而且,大部分时间 - 也就是说,如果我没有很多运气 - 我必须通过整个套牌十次,每次通过套牌最多十次换卡。大O,帮助我!
Big O进来并说:对于一副n张牌,这样排序将以O(N平方)时间完成。
为什么他说n平方?
嗯,你知道n平方是n次n。现在,我得到它:n卡检查,直到可能是通过甲板n次。这是两个循环,每个循环有n个步骤。这是很多工作要做的事情。很多工作,当然!
现在,当大O说它将需要O(n平方)工作时,他并不意味着n平方加在鼻子上。在某些情况下,它可能会少一些。但在最糟糕的情况下,它将接近n平方的工作量来对甲板进行分类。
现在,大O是我们的朋友。
Big O指出这一点:随着n变得越来越大,当我们对卡片进行分类时,这项工作比旧的只是添加这些工作要困难得多。我们怎么知道这个?
好吧,如果n变得很大,我们不关心我们可能会添加到n或n平方。
对于大n,n平方比n大。
Big O告诉我们,对东西进行排序比添加东西更难。对于大n,O(n平方)大于O(n)。这意味着:如果n变得非常大,那么对n个东西进行排序必须花费更多时间,而不是仅添加n个混合物。
Big O无法为我们解决问题。 Big O告诉我们工作有多难。
我有一副纸牌。我对它们进行了排序。你帮忙了感谢。
有没有更快捷的方式对牌进行排序?大O可以帮助我们吗?
是的,还有更快的方法!这需要一些时间来学习,但它的工作原理......它的工作速度非常快。您也可以尝试,但每走一步都要花时间,不要失去你的位置。
在这种对甲板进行分类的新方法中,我们不像前一段时间那样检查成对的牌。以下是您对此套牌进行排序的新规则:
一:我现在在甲板上选择一张牌。如果你愿意,你可以选择一个。 (我们第一次这样做,“我们现在处理的甲板部分”当然是整个甲板。)
二:我在您选择的那张牌上张开了牌组。这是什么意思;我该如何施展?好吧,我一个接一个地从开始卡开始,我找到一张比插卡更高的卡片。
三:我从终端卡开始,我找到一张比张卡更低的卡。
一旦我找到了这两张牌,我就换掉它们,继续寻找更多牌来换掉。也就是说,我回到第二步,然后在你选择的卡上张开更多。
在某些时候,这个循环(从2到3)将结束。当此搜索的两半在展开卡处相遇时结束。然后,我们刚刚用你在第一步中选择的牌张开了牌组。现在,开始附近的所有卡都比低位卡更低;并且靠近末端的卡比展开的卡更高。很酷的技巧!
四(这是有趣的部分):我现在有两个小甲板,比展开卡低一个,还有一个高。现在我走到每个小甲板上的第一步!也就是说,我从第一个小甲板上的第一步开始,当这项工作完成后,我从下一个小甲板上的第一步开始。
我将甲板分成几部分,然后对每个部分进行分类,更小,更小,有时候我没有更多的工作要做。现在这可能看起来很慢,包含所有规则。但请相信我,它根本不慢。它比第一种排序方式要少得多!
这叫什么?它被称为快速排序!那种是由一个叫C. A. R. Hoare的男人做的,他称之为快速排序。现在,Quick Sort一直在使用!
快速排序打破小型甲板。也就是说,它打破了小任务中的大任务。
嗯。我认为可能存在规则。为了使大任务变小,请将其分解。
这种很快。多快? Big O告诉我们:在这种情况下,这种类型需要完成O(n log n)工作。
它比第一种更快还是更快?大O,请帮忙!
第一种是O(n平方)。但快速排序是O(n log n)。你知道n log n小于n平方,对于大n,对吗?好吧,这就是我们知道快速排序很快的方法!
如果你必须对甲板进行排序,那么最好的方法是什么?好吧,你可以做你想做的事,但我会选择快速排序。
为什么选择快速排序?当然,我不喜欢工作!我希望我能尽快完成工作。
我如何知道快速排序的工作量较少?我知道O(n log n)小于O(n平方)。 O更小,因此Quick Sort工作量更少!
现在你认识我的朋友Big O.他帮助我们减少工作量。如果你知道大O,你也可以做更少的工作!
你跟我学到了这一切!你太聪明了!非常感谢你!
现在工作已经完成,让我们去玩吧!
[1]:有一种方法可以欺骗并将所有东西从一个添加到n,所有这些都是一次性的。一个名叫高斯的小孩在八岁的时候发现了这个。我不是那么聪明,所以don't ask me how he did it。
答案 21 :(得分:9)
我有更简单的方法来理解时间复杂性 计算时间复杂度的最常见指标是Big O表示法。这消除了所有常数因子,因此当N接近无穷大时,可以相对于N估计运行时间。一般来说,你可以这样想:
statement;
是不变的。语句的运行时间不会相对于N
而改变for ( i = 0; i < N; i++ )
statement;
是线性的。循环的运行时间与N成正比。当N加倍时,运行时间也是如此。
for ( i = 0; i < N; i++ )
{
for ( j = 0; j < N; j++ )
statement;
}
是二次的。两个循环的运行时间与N的平方成正比。当N加倍时,运行时间增加N * N.
while ( low <= high )
{
mid = ( low + high ) / 2;
if ( target < list[mid] )
high = mid - 1;
else if ( target > list[mid] )
low = mid + 1;
else break;
}
是对数的。算法的运行时间与N除以2的次数成正比。这是因为算法在每次迭代时将工作区域分成两半。
void quicksort ( int list[], int left, int right )
{
int pivot = partition ( list, left, right );
quicksort ( list, left, pivot - 1 );
quicksort ( list, pivot + 1, right );
}
N * log(N)。运行时间由N个循环(迭代或递归)组成,这些循环是对数的,因此算法是线性和对数的组合。
一般来说,对一个维度中的每个项目执行某些操作是线性的,对二维中的每个项目执行某些操作是二次的,将工作区域分成两半是对数的。还有其他Big O指标,如立方,指数和平方根,但它们并不常见。 Big O表示法被描述为O(),其中是度量。快速排序算法将被描述为O(N * log(N))。
注意:这些都没有考虑最佳,平均和最坏情况的措施。每个都有自己的Big O表示法。另请注意,这是一个非常简单的解释。 Big O是最常见的,但它也显示得更复杂。还有其他符号,如大欧米茄,小o和大theta。您可能不会在算法分析课程之外遇到它们。
答案 22 :(得分:9)
说你订购哈利波特:从亚马逊完成8-Film Collection [Blu-ray]并同时在线下载相同的电影收藏。您想测试哪种方法更快。交付大约需要一天到达,下载大约提前30分钟完成。大!所以这是一场紧张的比赛。
如果我订购了诸如指环王,暮光之城,黑暗骑士三部曲等多部蓝光电影,并同时在线下载所有电影,该怎么办?这一次,交付仍需要一天时间才能完成,但在线下载需要3天才能完成。 对于在线购物,购买的商品数量(输入)不会影响交货时间。输出是不变的。我们称之为 O(1)。
对于在线下载,下载时间与电影文件大小(输入)成正比。我们称之为 O(n)。
从实验中,我们知道网上购物比在线下载更好。理解大O表示法非常重要,因为它可以帮助您分析算法的可伸缩性和效率。
注意: Big O表示法表示算法的最坏情况。我们假设 O(1)和 O(n)是上述示例的最坏情况。
答案 23 :(得分:9)
假设我们正在谈论一个算法 A ,它应该对大小 n 的数据集做一些事情。
然后O( <some expression X involving n> )
表示简单的英语:
如果你在执行A时不走运,可能需要执行X(n)操作 完整。
实际上,某些功能(将它们视为 X(n)的实现)往往会经常发生。这些是众所周知的并且易于比较(示例:1
,Log N
,N
,N^2
,N!
等。)
通过在讨论 A 和其他算法时对这些进行比较,很容易根据可能(最坏情况)所需的操作次数对算法进行排名完成。
一般来说,我们的目标是找到或构建算法 A ,使其具有尽可能低的数字X(n)
。
答案 24 :(得分:8)
如果你头脑中有一个合适的无限概念,那么就有一个非常简短的描述:
Big O表示法告诉您解决无限大问题的成本。
此外
常数因素可以忽略不计
如果您升级到能够以两倍的速度运行算法的计算机,则大O符号不会注意到这一点。恒定因子的改进太小,甚至在大O符号的工作范围内都没有被注意到。请注意,这是大O符号设计的有意部分。
虽然任何东西都比较大&#34;然而,可以检测到恒定因子。
当有兴趣进行大小为&#34;大&#34;足以被视为近似无穷大,那么大O符号大约是解决问题的成本。
如果上述内容没有意义,那么你的头脑中没有兼容的直观无限概念,你应该忽视以上所有内容;我知道要使这些想法严格的唯一方法,或者如果它们已经不具有直觉意义就解释它们,那就是首先教你大量的符号或类似的东西。 (虽然,一旦你很好地理解了未来的大O符号,重新考虑这些想法可能是值得的)
答案 25 :(得分:7)
“Big O”符号的简单英语解释是什么?
非常快速注意:
“大O”中的O表示为“顺序”(或正是“顺序”)
所以你可以从字面上理解它用来订购比较它们的东西。
“Big O”有两件事:
Notations
实现上述两项。有七种最常用的符号
1
步完成的任务,非常好,订购了No.1 logN
步骤的任务,其良好,订购号为2 N
步骤完成任务,公平,第3号订单O(NlogN)
步骤结束任务,不好,订单号4 N^2
步骤完成任务,这很糟糕,订单号为5 2^N
步骤完成任务,这太可怕了,订单No.6 N!
步骤完成任务,这很糟糕,订单No.7 假设你得到符号O(N^2)
,不仅你清楚该方法需要N * N个步骤来完成一个任务,你也会发现它的排名并不好O(NlogN)
。
请注意行尾的顺序,以便您更好地理解。如果考虑所有可能性,则有超过7种符号。
在CS中,完成任务的一组步骤称为算法 在术语中,Big O表示法用于描述算法的性能或复杂性。
此外,Big O确定最坏情况或测量上限步骤 您可以参考Big-Ω(Big-Omega)获得最佳案例。
Big-Ω (Big-Omega) notation (article) | Khan Academy
<强>摘要强>
“Big O”描述了算法的性能并对其进行了评估。
或正式解决,“Big O”对算法进行分类并使比较过程标准化。
答案 26 :(得分:6)
最简单的查看方法(用简单的英语)
我们正在尝试查看输入参数的数量,如何影响算法的运行时间。如果应用程序的运行时间与输入参数的数量成正比,则称其为n的Big O.
上述陈述是一个良好的开端,但并非完全正确。
更准确的解释(数学)
假设
n =输入参数的数量
T(n)=表示算法运行时间的实际函数,作为n
的函数c =常数
f(n)=一种近似函数,表示算法的运行时间是n
的函数然后就Big O而言,只要满足以下条件,近似f(n)就足够了。
lim T(n) ≤ c×f(n)
n→∞
方程式读作 当n接近无穷大时,n的T小于或等于n的c倍f。
在大O符号中,这写为
T(n)∈O(n)
这是因为n的t在n的大O中。
返回英语
根据上面的数学定义,如果你说你的算法是n的大O,那就意味着它是n(输入参数的数量)或更快的函数。如果你的算法是n的大O,那么它也自动是n平方的大O.
n的大O意味着我的算法运行至少与此一样快。您无法查看算法的Big O表示法,并说它很慢。你只能说它快。
检查this以获取加州大学伯克利分校关于Big O的视频教程。它实际上是一个简单的概念。如果你听到Shewchuck教授(又名神级教师)解释它,你会说&#34;哦,这就是全部!&#34;。
答案 27 :(得分:5)
我发现了一个关于大O符号的非常好的解释,特别是对于一个对数学不太了解的人。
https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/
计算机科学中使用Big O表示法来描述性能 或算法的复杂性。 Big O专门描述了 最糟糕的情况,可以用来描述执行时间 所需的或所用的空间(例如在内存或磁盘上)由 算法
任何阅读编程珍珠或任何其他计算机科学的人 书籍并没有数学基础就会碰壁 当他们到达提及O(N log N)或其他似乎的章节时 疯狂的语法。希望这篇文章能帮助你获得一个 理解Big O和Logarithms的基础知识。
作为程序员第一,数学家第二(或者第三或第二) 第四)我找到了彻底了解Big O的最好方法 在代码中产生一些例子。所以,下面是一些常见的订单 增长以及可能的描述和示例。
O(1)
O(1)描述了一种始终在同一时间执行的算法 (或空格),与输入数据集的大小无关。
bool IsFirstElementNull(IList<string> elements) { return elements[0] == null; } O(N)
O(N)
O(N)描述了一种算法,其性能将线性增长 与输入数据集的大小成正比。这个例子 下面还演示了Big O如何倾向于最坏情况的表现 场景;在任何迭代期间都可以找到匹配的字符串 for循环,函数会提前返回,但Big O表示法会返回 总是假设算法将执行的上限 最大迭代次数。
bool ContainsValue(IList<string> elements, string value) { foreach (var element in elements) { if (element == value) return true; } return false; }
O(N 2 )
O(N 2 )表示直接表现的算法 与输入数据集大小的平方成正比。这是 与涉及数据嵌套迭代的算法相同 组。更深的嵌套迭代将导致O(N 3 ),O(N 4 )等。
bool ContainsDuplicates(IList<string> elements) { for (var outer = 0; outer < elements.Count; outer++) { for (var inner = 0; inner < elements.Count; inner++) { // Don't compare with self if (outer == inner) continue; if (elements[outer] == elements[inner]) return true; } } return false; }
O(2 Ñ)
O(2 N )表示一种算法,其增长率随着每个附加值的增加而翻倍 输入数据集。 O(2 N )函数的生长曲线是 指数 - 从非常浅的开始,然后迅速上升。一个 O(2 N )函数的一个例子是Fibonacci的递归计算 数:
int Fibonacci(int number) { if (number <= 1) return number; return Fibonacci(number - 2) + Fibonacci(number - 1); }
对数
对数稍微复杂一点,所以我会使用一个常见的 例如:
二进制搜索是一种用于搜索已排序数据集的技术。有用 通过选择数据集的中间元素,基本上是 中位数,并将其与目标值进行比较。如果值与之匹配 会回归成功。如果目标值高于值 探针元素将占据数据集的上半部分 对它执行相同的操作。同样,如果是目标值 低于它将执行的探测元素的值 对下半部分的操作。它将继续将数据减半 设置每次迭代,直到找到值或直到找到值 不再拆分数据集。
这种算法被描述为O(log N)。迭代减半 二进制搜索示例中描述的数据集产生增长 曲线在开始时达到峰值,并随着大小逐渐变平 例如,数据集增加了包含10个项目的输入数据集 需要一秒钟才能完成,包含100个项目的数据集 两秒钟,包含1000个项目的数据集将占用三个 秒。加倍输入数据集的大小几乎没有影响 它的增长是在算法的单次迭代之后的数据集 将减半,因此与输入数据集的一半相同 尺寸。这使得二进制搜索等算法非常有效 在处理大型数据集时。
答案 28 :(得分:4)
这是一个非常简化的解释,但我希望它涵盖了最重要的细节。
假设您处理问题的算法取决于某些“因素”,例如让我们将其设为N和X.
根据N和X,您的算法将需要一些操作,例如在最坏情况下它是3(N^2) + log(X)
操作。
由于Big-O不太关心常数因子(又称3),因此算法的Big-O为O(N^2 + log(X))
。它基本上可以转换'算法在最坏情况下需要的操作量'。
答案 29 :(得分:3)
如果我想向6岁的孩子解释这个,我会开始绘制一些函数f(x)= x和f(x)= x ^ 2例如,并询问孩子哪个函数将是上层函数页面顶部。然后我们将继续绘图并看到x ^ 2获胜。 “谁胜”实际上是当x趋于无穷大时增长得更快的函数。所以“函数x在x ^ 2的大O中”意味着当x趋于无穷大时,x比x ^ 2增长得慢。 当x趋于0时,可以做同样的事情。如果我们从0到1 x绘制这两个x的函数将是一个上函数,所以“函数x ^ 2在x的大O中为x倾向于0”。 当孩子长大后,我补充一点,Big O可以是一个不会增长但功能与给定功能相同的功能。此外,常数被丢弃。所以2x在x的Big O中。
答案 30 :(得分:3)
算法:解决问题的程序/公式
如何分析算法以及如何将算法相互比较?
示例:您和朋友被要求创建一个函数来对0到N之间的数字求和。您想出f(x)并且您的朋友想出了g(x)。两个函数具有相同的结果,但是具有不同的算法。为了客观地比较算法的效率,我们使用 Big-O表示法。
Big-O表示法描述当输入变得任意大时,运行时相对于输入的增长速度。
3个关键要点:
空间复杂性除了时间复杂性之外,我们还关心空间复杂性(算法使用多少内存/空间)。我们不是检查操作时间,而是检查内存分配的大小。
答案 31 :(得分:2)
Big O是表示任何函数上限的一种方法。我们通常用它来表示一个告诉算法运行时间的函数的上界。
Ex:f(n)= 2(n ^ 2)+ 3n是表示假设算法运行时间的函数,Big-O表示法基本上给出了该函数的上限,即O(n ^ 2)
这种符号基本上告诉我们,对于任何输入&#39; n&#39;运行时间不会大于Big-O表示法所表示的值。
此外,同意以上所有详细答案。希望这会有所帮助!!
答案 32 :(得分:2)
Big O正在描述一类函数。
它描述了大输入值的函数增长速度。
对于给定函数f,O(f)描述所有函数g(n),你可以找到它们的n0和常数c,这样所有g(n)的n> = n0的值都小于或等于到c * f(n)
在较少的数学词中,O(f)是一组函数。 也就是说,从某个值n0开始,所有函数的增长速度都比f慢。或者像f一样快。
如果f(n)= n则
g(n)= 3n在O(f)中。因为常数因素无关紧要 h(n)= n + 1000在O(f)中,因为对于所有超过1000的值,它可能更大,但对于大O,只有巨大的输入很重要。
然而i(n)= n ^ 2不在O(f)中,因为二次函数的增长速度快于线性函数。
答案 33 :(得分:2)
普通英语中的大O就像&lt; =(小于或等于)。当我们说两个函数f和g时,f = O(g)意味着f <= g。
然而,这并不意味着对于任何n f(n)&lt; = g(n)。实际上,这意味着 f在增长方面小于或等于g 。这意味着在点之后 f(n)&lt; = c * g(n)如果 c是常数。 之后意味着比所有n&gt; = n0,其中n0 是另一个常数。
答案 34 :(得分:1)
“ Big O”符号的简单英语解释是什么?
我要强调的是,当算法的输入大小变得很大时,“大O”符号的驱动动机是一回事。 ,描述算法度量的方程式的,系数,项变得微不足道,以至于我们忽略。在忽略了方程的某些部分之后仍然存在的方程部分称为算法的“大O”符号。
因此,如果输入大小不是太大,则“大O”符号(上限)的想法将不重要。
Les说您想量化以下算法的性能
int sumArray (int[] nums){
int sum=0; // taking initialization and assignments n=1
for(int i=0;nums.length;i++){
sum += nums[i]; // taking initialization and assignments n=1
}
return sum;
}
在上述算法中,假设您发现T(n)
如下(时间复杂度):
T(n) = 2*n + 2
要找到其“ Big O”符号,我们需要考虑很大的输入量:
n= 1,000,000 -> T(1,000,000) = 2,000,002
n=1,000,000,000 -> T(1,000,000,000) = 2,000,000,002
n=10,000,000,000 -> T(10,000,000,000) = 20,000,000,002
让我们为另一个功能F(n) = n
n= 1,000,000 -> F(1,000,000) = 1,000,000
n=1,000,000,000 -> F(1,000,000,000) = 1,000,000,000
n=10,000,000,000 -> F(10,000,000,000) = 10,000,000,000
正如您所见,输入大小变得太大,T(n)
大约等于或越来越接近F(n)
,因此常数2
和系数2
变得微不足道,现在出现了“大O”符号的想法,
O(T(n)) = F(n)
O(T(n)) = n
我们说T(n)
的大O是n
,符号是O(T(n)) = n
,它是T(n)
的上限,因为n
得到< strong>太大。同样的步骤适用于其他算法。
答案 35 :(得分:1)
从长远来看,它表示算法的速度。
以字面意义进行类比,您不必担心跑步者可以以多快的速度冲刺100m甚至5k。您更关心马拉松运动员,最好是超级马拉松运动员(除此之外,对跑步的类比也中断了,您必须恢复到“长期”的隐喻含义。)
您可以放心在这里停止阅读。
我添加此答案是因为我对其余答案的数学和技术水平感到惊讶。第一句话中的“长期运行”的概念与任意耗时的计算任务有关。与受人的能力限制的运行不同,要完成某些算法,计算任务可能甚至需要花费数百万年的时间。
所有这些数学对数和多项式如何?事实证明,算法在本质上与这些数学术语相关。如果您正在测量街区上所有孩子的身高,这将花费您很多孩子的时间。这与 n ^ 1 或仅仅是 n 的概念本质上相关,其中 n 仅仅是该区块上孩子的数量。在超级马拉松的情况下,您正在测量城市中所有孩子的身高,但随后您必须忽略旅行时间,并假设他们在一条直线上都可以使用(否则,我们将跳过当前的说明)。
假设您尝试按最短身高到最长身高的顺序排列由孩子身高组成的列表。如果只是您附近的孩子,您可能只需关注一下并提出订购清单。这是“冲刺”的类比,我们真的不在乎计算机科学中的冲刺,因为为什么您可以在眼中某事时使用计算机?
但是,如果您要安排城市中所有孩子的身高列表,或者更好的是您所在的国家/地区,那么您会发现如何做到这一点与数学上的 log 相关联和 n ^ 2 。遍历您的清单以找到最矮的孩子,在一个单独的笔记本中写下他的名字,然后将其从原始笔记本中划掉,这与数学上的 n ^ 2 本质上是联系在一起的。如果您打算先安排笔记本的一半,然后再安排另一半,然后再组合结果,那么您将得出固有与对数相关的方法。
最后,假设您首先必须去商店购买卷尺。这是在短距离冲刺(例如,测量街区上的孩子)时需要付出努力的结果的示例,但是当您测量城市中的所有孩子时,您可以放心地忽略这笔费用。这是与低阶多项式项的数学下降的内在联系。
我希望我已经解释了big-O表示法仅是从长远来看的,数学与计算方法具有内在的联系,而数学术语的减少和其他简化与a的长期存在有关。相当常识的方式。
一旦意识到这一点,您就会发现big-O真的非常容易,因为所有艰苦的高中数学都很容易消失。唯一困难的部分是分析算法以识别数学项,但是通过一些实践,您可以在分析过程中开始删除术语,并安全地忽略算法的大部分,仅关注与big-O相关的部分。即您应该能够应付大多数情况。
开心的大O-ing,这是我最喜欢的计算机科学知识-发现某件事比我想象的要容易得多,然后当初学者受到恐吓时,我可以在Google采访中炫耀,哈哈。< / p>
答案 36 :(得分:1)
已经发布了一些很好的答案,但是我想以其他方式做出贡献。如果您想直观地了解正在发生的一切,则可以假定编译器可以在1秒钟内执行接近10 ^ 8的操作。如果输入以10 ^ 8给出,则您可能需要设计一种以线性方式运行的算法(例如非嵌套的for循环)。 下表是可以帮助您快速确定要计算的算法类型的表;)
答案 37 :(得分:1)
当我们有一个像f(n) = n+3
这样的函数,并且我们想知道当n
接近无穷大时图的样子时,我们只去掉所有常量和低阶项,因为它们什么时候都不重要n
变大了。
剩下f(n) = n
了,所以为什么我们不能只使用它,为什么我们需要寻找f(n) = n+3
函数之上和之下的某个函数,那么大的O和大的Omega。 / p>
因为当f(n) = n
接近无穷大时说函数只是n
是不正确的,因此,为了正确起见,我们描述了f(n) = n+3
所在的区域。我们对图的确切位置不感兴趣,因为低阶项和常数不会显着改变图的增长,因此我们对边界之间的区域感兴趣,如果图是{{ 1}}
仅删除常数项和低阶项就是发现上下函数的过程。
如果您可以找到一个常数,可以将n+3
函数乘以一个常数,这样对于每个f(n) = n
,输出就更大(或更小),按定义是一个函数的下限或上限用于下限),而不是原始功能:
n
是的,f(n) = n*C > f(n) = n+3
可以做到,因此我们的函数C = 2
可以成为我们的f(n) = n
函数的上限。
下界相同:
f(x) = x+3
f(n) = n*C < f(n) = n+3
会做到
因此,C = -2
是f(x) = n
的上限和下限,因为它的O和Omega都比其Theta大,这意味着其紧密结合。
这么大的O也可能是f(x) = x+3
,因为它满足条件f(x) = x^2
。它位于f(n) = n^2*C > f(n) = n+3
图的上方,但是此上限和下限之间的区域不如我们先前的上限f(n) = n+3
精确。
答案 38 :(得分:0)
大O - 经济观点。
我最喜欢用英语单词来描述这个概念,就是随着它变得越来越大,你为任务付出的价格。
将其视为经常性成本,而不是您在开始时支付的固定成本。从大局来看,固定成本可以忽略不计,因为成本只会增加而且会增加。我们想要衡量它们增长的速度以及它们对于我们为设置提供的原材料加起来的速度 - 问题的大小。
但是,如果初始设置成本很高并且您只生产少量产品,那么您可能需要查看这些初始成本 - 它们也称为常量。
因为从长远来看这些常数并不重要,所以这种语言允许我们讨论除了我们运行它的基础设施之外的任务。因此,工厂可以在任何地方,工人可以是任何人 - 它都是肉汁。但随着您的投入和产出的增长,工厂的规模和工人的数量将是我们可能长期变化的事情。
因此,这将成为一个大图近似你需要花多少钱来运行一些东西。由于时间和空间是经济数量(即它们是有限的),因此它们都可以使用这种语言表达。
技术说明:时间复杂度的一些例子 - O(n)通常意味着如果问题的大小如此,我至少必须看到一切。 O(log n)通常意味着我将问题的大小减半并检查并重复,直到任务完成。 O(n ^ 2)意味着我需要看一对事物(比如n人之间的派对握手)。
答案 39 :(得分:0)
TLDR:Big O用数学术语解释算法的性能。
较慢的算法倾向于在n处运行x或许多的幂,取决于它的深度,而像二进制搜索这样的较快的算法在O(log n)处运行,这使得它随着数据集变大而运行得更快。大O可以使用n来解释其他术语,或者甚至不使用n来解释(即:O(1))。
可以计算Big O查看算法中最复杂的行。
对于小型或未排序的数据集,Big O可能会令人惊讶,因为对于较小或未排序的集合,二元搜索等n log n复杂度算法可能会很慢,对于线性搜索与二分查找的简单运行示例,请查看我的JavaScript例如:
https://codepen.io/serdarsenay/pen/XELWqN?editors=1011(下面写的算法)
function lineerSearch() {
init();
var t = timer('lineerSearch benchmark');
var input = this.event.target.value;
for(var i = 0;i<unsortedhaystack.length - 1;i++) {
if (unsortedhaystack[i] === input) {
document.getElementById('result').innerHTML = 'result is... "' + unsortedhaystack[i] + '", on index: ' + i + ' of the unsorted array. Found' + ' within ' + i + ' iterations';
console.log(document.getElementById('result').innerHTML);
t.stop();
return unsortedhaystack[i];
}
}
}
function binarySearch () {
init();
sortHaystack();
var t = timer('binarySearch benchmark');
var firstIndex = 0;
var lastIndex = haystack.length-1;
var input = this.event.target.value;
//currently point in the half of the array
var currentIndex = (haystack.length-1)/2 | 0;
var iterations = 0;
while (firstIndex <= lastIndex) {
currentIndex = (firstIndex + lastIndex)/2 | 0;
iterations++;
if (haystack[currentIndex] < input) {
firstIndex = currentIndex + 1;
//console.log(currentIndex + " added, fI:"+firstIndex+", lI: "+lastIndex);
} else if (haystack[currentIndex] > input) {
lastIndex = currentIndex - 1;
//console.log(currentIndex + " substracted, fI:"+firstIndex+", lI: "+lastIndex);
} else {
document.getElementById('result').innerHTML = 'result is... "' + haystack[currentIndex] + '", on index: ' + currentIndex + ' of the sorted array. Found' + ' within ' + iterations + ' iterations';
console.log(document.getElementById('result').innerHTML);
t.stop();
return true;
}
}
}
答案 40 :(得分:0)
从 (source) 可以读到:
<块引用>Big O 表示法是一种数学表示法,描述了极限 当参数趋向于特定时函数的行为 值或无穷大。 (..) 在计算机科学中,大 O 符号用于对算法进行分类 根据他们的运行时间或空间需求如何增长作为 输入大小增加。
Big O
表示法不代表每个 si 的函数,而是具有某个渐近上限的 set of functions;可以从 source 中读到:
Big O 表示法根据函数的增长来表征函数
速率:具有相同增长率的不同函数可能是
使用相同的 O
符号表示。
非正式地,在计算机科学 time-complexity 和 space-complexity 理论中,人们可以将 Big O
表示法视为算法的分类,其中包含有关时间和空间的某些最坏情况,分别。例如,O(n)
:
如果算法的时间/空间复杂度为 O(n),则称其采用线性时间/空间或 O(n) 时间/空间。非正式地,这意味着运行时间/空间最多随输入的大小 (source) 线性增加。
和 O(n log n)
为:
对于某个正常数 k,如果 T(n) = O(n log^k n),则称算法在拟线性时间/空间中运行;线性时间/空间是 k = 1 (source) 的情况。
尽管如此,通常这种宽松的措辞通常用于量化(对于最坏的情况)一组算法与另一组算法在输入大小增加方面的表现。要比较两类算法(例如,O(n log n)
和 O(n)
),应该分析两类算法随着其输入大小的增加(即, n) 对于最坏的情况;当趋于无穷大时分析 n
在上图中,big-O
表示所绘制函数的渐近最小上限之一,并且不涉及集合 O(f(n))
。
例如比较O(n log n)
vs. O(n)
,就像我们在特定输入后在图像中看到的那样,O(n log n)
(绿线)比O(n)
(黄线)增长得更快)。这就是为什么(对于最坏的情况)O(n)
比 O(n log n)
更可取,因为可以增加输入大小,并且前者的增长率比后者慢。