web-dev-qa-db-ja.com

「O(1)アクセス時間」とはどういう意味ですか?

この用語「O(1)アクセス時間」は「クイック」を意味していましたが、その意味がわかりません。同じコンテキストで私が見る他の用語は、「O(n)アクセス時間」です。誰かがこれらの用語の意味を簡単な方法で説明してもらえますか?

関連項目

103
Grygori

複雑さの順序を読みたいと思うでしょう。

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

つまり、O(1)は、セット内のデータ量に関係なく、14ナノ秒、または3分などの一定の時間がかかることを意味します。

O(n)は、セットのサイズに比例した時間を要するため、サイズの2倍のセットには2倍の時間がかかることを意味します。おそらく、これらの1つに100万個のオブジェクトを入れたくないでしょう。

142
Karl

要するに、コレクション内のアイテムの数が少ない場合でも、非常に多くの場合でも(ハードウェアの制約内で)コレクション内の値を検索するのに同じ時間がかかることを意味します

O(n)は、アイテムの検索にかかる時間がコレクション内のアイテムの数に比例することを意味します。

これらの典型的な例は、サイズに関係なく直接アクセスできる配列と、特定のアイテムにアクセスするために最初から順番に走査する必要があるリンクリストです。

通常説明される他の操作は挿入です。コレクションは、アクセスのためにO(1)であるが、挿入のためにO(n)である場合があります。中央では、各アイテムを次のスロットにコピーして、右に移動する必要があります。

現在この質問に回答しているすべての回答は、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 * n_によって上にバインドされるような定数cがあることを意味します。ここで、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;
}
_

これは、各要素を1つずつ検査する配列を反復処理する必要があるためです。

18
jason

O(1)は、何かにアクセスする時間がコレクション内のアイテムの数に依存しないことを意味します。

O(N)は、アイテムにアクセスする時間がコレクション内のアイテムの数(N)に比例することを意味します。

14
Rob Walker

O(1)は必ずしも「すばやく」を意味するわけではありません。これは、かかる時間が一定であり、関数への入力のサイズに基づいてnotであることを意味します。定数は高速でも低速でもかまいません。 O(n)は、関数にかかる時間がnで示される関数への入力のサイズに正比例して変化することを意味します。これも高速または低速ですが、 nのサイズが大きくなると遅くなります。

13
Bill the Lizard

Big O表記 と呼ばれ、さまざまなアルゴリズムの検索時間を記述します。

O(1)は、最悪の場合の実行時間が一定であることを意味します。ほとんどの場合、実際にコレクションを検索する必要はなく、すぐに検索対象を見つけることができます。

8
alexn

「ビッグO表記」は、アルゴリズムの速度を表現する方法です。 nは、アルゴリズムが処理しているデータの量です。 O(1)は、データの量に関係なく、一定時間で実行されることを意味します。 O(n)は、データ量に比例することを意味します。

4
Zifre

O(1)は、データセットnに関係なく、常に同時に実行されます。 O(1)の例は、インデックスを使用してその要素にアクセスするArrayListです。

O(n)は線形次数とも呼ばれ、パフォーマンスは線形に増加し、入力データのサイズに正比例します。 O(n)の例は、ランダムな位置でのArrayListの挿入と削除です。ランダムな位置での後続の挿入/削除のたびに、ArrayListの要素は内部の左右に移動します。線形構造を維持するための配列。新しい配列の作成や、高価な処理時間を要する古い配列から新しい配列への要素のコピーについては言うまでもなく、パフォーマンスが低下します。

4
leCodera

基本的に、O(1)は計算時間が一定であることを意味し、O(n)は線形に依存することを意味します入力のサイズ-つまり、配列をループ処理するとO(n)-ループのみ--計算中にアイテムの数に依存するため通常の数値までの最大値はO(1)です。

ウィキペディアも役立ちます: http://en.wikipedia.org/wiki/Computational_complexity_theory

3
Seb

O(1)とO(n)=を区別する最も簡単な方法は、配列とリストを比較することです。

配列の場合、正しいインデックス値があれば、即座にデータにアクセスできます。 (インデックスがわからず、配列をループする必要がある場合は、O(1)もうなくなります)

リストについては、インデックスを知っているかどうかにかかわらず、常にループする必要があります。

3
codingbear

これは、アクセス時間が一定であることを意味します。 100個または100,000個のレコードからアクセスしている場合でも、取得時間は同じです。

対照的に、O(n)アクセス時間は、取得時間はアクセス元のレコード数に正比例することを示します。

1
Rob Hruska

これは、アクセスに一定の時間がかかること、つまりデータセットのサイズに依存しないことを意味します。 O(n)は、アクセスがデータセットのサイズに線形に依存することを意味します。

Oはbig-Oとも呼ばれます。

1
dirkgently

以下に簡単な例えを示します。 O(1)を使用してオンラインで映画をダウンロードするとします。1つの映画をダウンロードするのに5分かかる場合でも、20の映画をダウンロードするのに同じ時間がかかります。したがって、ダウンロードする映画の数は問題ではありません。1つでも20の映画でも、同じ時間(5分)がかかります。この類推の通常の例は、1つでも5つでも、ムービーライブラリに移動するときに、一度に選択するだけです。したがって、同じ時間を費やしています。

ただし、O(n)では、1つの映画をダウンロードするのに5分かかる場合、10本の映画をダウンロードするのに約50分かかります。そのため、時間は一定ではなく、ダウンロードする映画の数に比例します。

1

アルゴリズムの紹介:Cormen、Leiserson、Rivest&Steinによる第2版は、44ページで次のように述べています。

定数は0次多項式であるため、定数関数はTheta(n ^ 0)またはTheta(1)として表現できます。ただし、後者の表記法は軽微な乱用です。これは、どの変数が無限に向かう傾向があるかが明確ではないためです。多くの場合、変数Theta(1)を使用して、ある変数に関して定数または定数関数を意味します。 ... O(g(n))で示し​​ます...関数のセットf(n) 0などの正の定数cとn0が存在するように= <= f(n) <= c * g(n)すべてのn> = n0 ....に注意してください。f(n) = Theta(g(n) )はf(n) = O(g(n))を意味します。シータ表記はO表記よりも強いためです。

アルゴリズムがO(1)時間で実行される場合、漸近的に変数に依存しないことを意味します。つまり、1倍したときに1よりも大きい正の定数が少なくとも1つ存在することを意味します。一定量を超えるnの値に対する関数の漸近的な複雑さ(〜ランタイム)技術的には、O(n ^ 0)時間です。

1
P. Myer Nore