“ O(1)访问时间”是什么意思?


Answers:


161

您将要阅读复杂性顺序。

http://en.wikipedia.org/wiki/Big_O_notation

简而言之,O(1)表示它花费恒定的时间,例如14纳秒或3分钟,而不管集合中的数据量如何。

O(n)表示它花费的时间与集合的大小呈线性关系,因此,两倍大小的集合将花费两倍的时间。您可能不想在其中一个对象中放入一百万个对象。


66
要学究一点,并不意味着运行时间(或操作数等)是恒定的。这意味着存在一个常量,使得运行时(或操作数等)在上面受该常量限制。运行时中仍然可能存在较大差异:例如int main() { int n; cin >> n; if(n == 0) { sleep(60 * 60 * 24 * 365); } cout << n; }is O(1)
杰森

伟大的见解@jason!
克里斯·鲁斯凯

35

从本质上讲,这意味着您需要花费相同的时间来查询集合中的值,无论您的集合中的项目是少量还是非常多(在硬件限制内)

O(n)表示查找项目所花费的时间与集合中项目的数量成正比。

这些的典型示例是数组(无论大小如何都可以直接访问)和链表(必须从头开始按顺序遍历才能访问给定项)。

通常讨论的另一个操作是插入。集合可以是O(1)用于访问,而O(n)用于插入。实际上,数组确实具有这种行为,因为要在中间插入一个项目,您必须将每个项目复制到以下插槽中,以将每个项目向右移动。


21

当前回答该问题的每个答案都告诉您,O(1)平均时间是指恒定时间(无论发生什么测量;可能是运行时间,操作次数等)。这是不准确的。

要说运行时是O(1)指有一个常量c,使运行时在上方受限制c,与输入无关。例如,返回n整数数组的第一个元素是O(1)

int firstElement(int *a, int n) {
    return a[0];
}

但是这个功能O(1)也是:

int identity(int i) {
    if(i == 0) {
        sleep(60 * 60 * 24 * 365);
    }
    return i;
}

此处的运行时间的上限为1年,但大多数情况下,运行时间为纳秒级。

要说运行时是O(n)指有一个常量c,使运行时在上方受限制c * n,其中n测量输入的大小。例如,n通过以下算法查找未排序的整数数组中特定整数的出现次数是O(n)

int count(int *a, int n, int item) {
    int c = 0;
    for(int i = 0; i < n; i++) {
        if(a[i] == item) c++;
    }
    return c;
}

这是因为我们必须遍历数组,一次检查每个元素。


19

O(1)表示访问某些内容的时间与集合中项目的数量无关。

O(N)表示访问项目的时间与集合中项目的数量(N)成比例。


14

O(1)不一定表示“快速”。这意味着花费的时间是恒定的,而不是基于函数输入的大小。常数可以快也可以慢。O(n)表示函数花费的时间将直接与函数输入的大小成正比,以n表示。同样,它可能快也可能慢,但是随着n的增加,它会变慢。


9

它称为Big O表示法,描述了各种算法的搜索时间。

O(1)表示最坏情况下的运行时间是恒定的。对于大多数情况,这意味着您根本不需要搜索集合,就可以立即找到要搜索的内容。


将“搜索时间”替换为“最坏情况下的运行时间”,我与您同在。
詹森·普尼扬

2
@Seb:我认为这只是他的错误用语,特别是因为OP询问访问时间。
jkeys

6

O(1)无论数据集n是什么,总是在同一时间执行。O(1)的一个示例是使用索引访问其元素的ArrayList。

O(n)也称为线性顺序,性能将线性增长,并与输入数据的大小成正比。O(n)的一个示例是在随机位置插入和删除ArrayList。由于随后在随机位置进行的每个插入/删除操作都将导致ArrayList中的元素在其内部数组中向左移动,以保持其线性结构,更不用说创建新数组和从旧数组复制元素了。新的阵列占用大量的处理时间,因此会损害性能。


4

“大O表示法”是表达算法速度的一种方法。n是算法正在处理的数据量。O(1)意味着无论有多少数据,它都会在恒定时间内执行。O(n)表示它与数据量成正比。


3

基本上,O(1)表示其计算时间是恒定的,而O(n)表示其将线性地取决于输入的大小-即遍历数组具有O(n)-只是循环-,因为它取决于数量项,同时计算到普通数之间的最大值为O(1)。

维基百科也可能有所帮助:http : //en.wikipedia.org/wiki/Computational_complexity_theory


3

区分O(1)和O(n)的最简单方法是比较数组和列表。

对于数组,如果您具有正确的索引值,则可以立即访问数据。(如果您不知道索引并且必须遍历数组,那么它将不再是O(1))

对于列表,无论您是否知道索引,都始终需要遍历它。


我一直在寻找O(1)的示例,只有这个答案对此有解释。
neelmeg

3

这是一个简单的类比;想象一下,您使用O(1)在线下载电影,如果花5分钟才能下载一部电影,那么仍然需要花费相同的时间来下载20部电影。因此,无论您要下载多少部电影,无论是一部电影还是20部电影,它们都将花费相同的时间(5分钟)。这种类比的一个正常示例是,当您进入电影库时,无论是拍摄一部电影还是5部电影,您都只需立即选择它们。因此花费相同的时间。

但是,对于O(n),如果需要花费5分钟下载一部电影,则将花费大约50分钟下载10部电影。因此,时间不是恒定的,或者与下载的电影数量成比例。


1

这意味着访问时间是恒定的。无论您要访问100条记录还是100,000条记录,检索时间都是相同的。

相反,O(n)访问时间将表明检索时间与您从中访问的记录数成正比。


1

这意味着访问需要固定的时间,即不依赖于数据集的大小。O(n)表示访问将线性依赖于数据集的大小。

O也称为big-O。


1

算法简介:Cormen,Leiserson,Rivest&Stein撰写的第二版在第44页上说:

由于任何常数都是0度多项式,因此我们可以将任何常数函数表示为Theta(n ^ 0)或Theta(1)。后一种表示法是次要的滥用,因为尚不清楚哪个变量趋于无穷大。我们将经常使用符号Theta(1)来表示某个变量的常数或常数函数。...我们用O(g(n))表示...函数f(n)的集合,使得存在正常数c和n0,使得0 <= f(n)<= c * g(n)对于所有n> = n0。...请注意,f(n)= Theta(g(n))意味着f(n)= O(g(n)),因为Theta表示法比O表示法更强。

如果算法以O(1)的时间运行,则意味着渐近不依赖于任何变量,这意味着存在至少一个正常数,乘以1大于该函数的渐近复杂度(〜运行时)对于大于一定数量的n值。从技术上讲,这是O(n ^ 0)时间。


-2

O(1)表示随机访问。在任何随机存取存储器中,在任何位置访问任何元素所花费的时间都是相同的。这里的时间可以是任何整数,但是唯一要记住的是,在第(n-1)或第n个位置检索元素所花费的时间将是相同的(即常数)。

而O(n)取决于n的大小。


它与随机访问没有关系-有关此信息的更多信息,请参阅在此答案之前将近一年发布的接受答案
Krease

-3

根据我的观点,

O(1)表示一次执行一项操作或一条指令的时间为一次,在算法的时间复杂度分析中为最佳情况。


6
更加努力。该特定问题不仅需要一个观点,还需要一个明确的定义。
Alfabravo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.