Что означает «время доступа O (1)»?

127

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

Смотрите также

Сообщество
источник
Это может помочь: stackoverflow.com/questions/471199/…
Mehrdad Afshari

Ответы:

161

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

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

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

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

Карл
источник
66
Если говорить педантично, это не означает, что время выполнения (или количество операций и т. Д.) Постоянно. Это означает, что существует такая константа, что время выполнения (или количество операций и т. Д.) Ограничено сверху константой. Во время выполнения все еще может быть большой разброс: например, int main() { int n; cin >> n; if(n == 0) { sleep(60 * 60 * 24 * 365); } cout << n; }есть O(1).
Джейсон 08
Отличное понимание @jason!
Крис Рускай
35

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

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

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

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

SingleNegationElimination
источник
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) означает, что время работы в наихудшем случае постоянно. В большинстве случаев это означает, что вам не нужно искать в коллекции, вы можете сразу найти то, что ищете.

AlexN
источник
Замените «время поиска» на «время работы в худшем случае», и я с вами.
Джейсон Пуньон
2
@Seb: Я думаю, что с его стороны это неправильно, особенно потому, что OP спросил о времени доступа.
jkeys
6

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

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

leCodera
источник
4

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

Zifre
источник
3

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

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

Себ
источник
3

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

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

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

codingbear
источник
Я искал пример O (1), и только в этом ответе есть объяснение.
neelmeg
3

Вот простая аналогия; Представьте, что вы загружаете фильмы онлайн, с помощью O (1), если для загрузки одного фильма требуется 5 минут, то же самое время потребуется для загрузки 20 фильмов. Поэтому неважно, сколько фильмов вы загружаете, они займут одинаковое время (5 минут), будь то один фильм или 20. Обычный пример этой аналогии - когда вы заходите в библиотеку фильмов, берете ли вы один фильм или пять, вы просто выбираете их сразу. Следовательно, тратить то же время.

Однако с O (n), если для загрузки одного фильма требуется 5 минут, для загрузки 10 фильмов потребуется около 50 минут. Таким образом, время не является постоянным или каким-то образом пропорционально количеству фильмов, которые вы загружаете.

Ambroze kweronda
источник
1

Это означает, что время доступа постоянно. Независимо от того, получаете ли вы доступ к 100 или 100 000 записей, время получения будет одинаковым.

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

Роб Хруска
источник
1

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

Буква O также известна как big-O.

dirkgently
источник
1

Введение в алгоритмы: второе издание Cormen, Leiserson, Rivest & Stein говорит на странице 44, что

Поскольку любая константа является полиномом нулевой степени, мы можем выразить любую постоянную функцию как 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), это означает, что асимптотически не зависит от какой-либо переменной, а это означает, что существует по крайней мере одна положительная константа, которая при умножении на единицу превышает асимптотическую сложность (~ время выполнения) функции для значений n выше определенной суммы. Технически это время O (n ^ 0).

П. Майер Нор
источник
-2

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

Тогда как O (n) зависит от размера n.

Басант
источник
Это не имеет ничего общего с произвольным доступом - см. Принятый ответ, опубликованный почти за год до этого ответа, для получения дополнительной информации
Krease
-3

На мой взгляд,

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

amarjeet
источник
6
Стараться. Этот конкретный вопрос требует не только перспективы, но и четкого определения.
Alfabravo