Что означает «время доступа O (1)»? - PullRequest
100 голосов
/ 30 марта 2009

Я видел, как этот термин «O (1) время доступа» имел обыкновение означать «быстро», но я не понимаю, что это значит. Другой термин, который я вижу в этом же контексте: «O (n) access time». Может ли кто-нибудь объяснить простым способом, что означают эти термины?

См. Также

Ответы [ 16 ]

139 голосов
/ 30 марта 2009

Вы захотите прочитать о Ордене сложности.

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

Короче говоря, O (1) означает, что это занимает постоянное время, например, 14 наносекунд или три минуты, независимо от количества данных в наборе.

O (n) означает, что требуется количество времени, линейное с размером набора, поэтому набор, в два раза превышающий размер, будет занимать в два раза больше времени. Вы, вероятно, не хотите помещать миллион объектов в один из них.

31 голосов
/ 30 марта 2009

По сути, это означает, что поиск значения в вашей коллекции занимает одинаковое количество времени, независимо от того, есть ли у вас небольшое количество элементов в коллекции или очень много (в рамках ограничений вашего оборудования)

O (n) будет означать, что время, необходимое для поиска предмета, пропорционально количеству предметов в коллекции.

Типичными примерами этого являются массивы, к которым можно обращаться напрямую, независимо от их размера, и связанные списки, которые необходимо просмотреть для начала, чтобы получить доступ к данному элементу.

Другая обычно обсуждаемая операция - вставка. Коллекция может быть O (1) для доступа, но O (n) для вставки. На самом деле массив имеет именно такое поведение, потому что для вставки элемента посередине вам нужно переместить каждый элемент вправо, скопировав его в следующий слот.

17 голосов
/ 08 января 2010

Каждый ответ, который в настоящее время отвечает на этот вопрос, говорит вам, что 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;
}

Это потому, что мы должны перебирать массив, проверяя каждый элемент по одному.

14 голосов
/ 30 марта 2009

O (1) означает, что время доступа к чему-либо не зависит от количества элементов в коллекции.

O (N) будет означать, что время для доступа к элементу пропорционально количеству (N) элементов в коллекции.

13 голосов
/ 30 марта 2009

O (1) не обязательно означает «быстро». Это означает, что время, которое требуется, является постоянным, а не в зависимости от размера входа в функцию. Константа может быть быстрой или медленной. O (n) означает, что время, которое занимает функция, будет изменяться прямо пропорционально размеру входа в функцию, обозначаемому n. Опять же, он может быть быстрым или медленным, но он будет медленнее при увеличении размера n.

8 голосов
/ 30 марта 2009

Он называется Big O нотацией и описывает время поиска для различных алгоритмов.

O (1) означает, что время выполнения в худшем случае является постоянным. В большинстве случаев это означает, что вам фактически не нужно искать коллекцию, вы сразу же найдете то, что ищете.

4 голосов
/ 29 августа 2016

O(1) всегда выполняется в одно и то же время независимо от набора данных n. Примером O (1) может быть ArrayList, обращающийся к своему элементу с индексом.

O(n), также известный как линейный порядок, производительность будет расти линейно и прямо пропорционально размеру входных данных. Примером O (n) может быть вставка и удаление ArrayList в произвольной позиции. Поскольку каждая последующая вставка / удаление в произвольной позиции приведет к смещению элементов в ArrayList влево-вправо от его внутреннего массива, чтобы сохранить его линейную структуру, не говоря уже о создании новых массивов и копировании элементов из старого к новому массиву, который, следовательно, занимает дорогое время обработки, ухудшает производительность.

4 голосов
/ 30 марта 2009

«Big O notation» - это способ выразить скорость алгоритмов. n - количество данных, с которыми работает алгоритм. O(1) означает, что независимо от объема данных он будет выполняться за постоянное время. O(n) означает, что оно пропорционально количеству данных.

3 голосов
/ 30 марта 2009

Самый простой способ различить O (1) и O (n) - это сравнение массива и списка.

Для массива, если у вас есть правильное значение индекса, вы можете получить мгновенный доступ к данным. (Если вы не знаете индекс и вынуждены циклически проходить по массиву, он больше не будет O (1))

Для списка, вы всегда должны проходить через него, знаете ли вы индекс или нет.

3 голосов
/ 30 марта 2009

В основном, O (1) означает, что его время вычислений является постоянным, в то время как O (n) означает, что оно будет линейно зависеть от размера ввода, то есть цикл в массиве имеет O (n) зацикливание - потому что оно зависит от количества элементов, а при расчете максимума между обычными числами есть O (1).

Википедия также может помочь: http://en.wikipedia.org/wiki/Computational_complexity_theory

...