ビッグO表記配列とリンクリスト挿入:
配列の学術文献によると、定数O(1)です。リンクリストの場合、線形O(n)です。
配列は1つの乗算と加算のみを取ります。
連続したメモリに配置されていないリンクリストは、トラバースを必要とします。
この質問は、O(1)とO(n)はそれぞれ配列とリンクリストのインデックス作成/検索コストを正確に記述していますか?
O(1)
は、配列の最後に挿入することを正確に説明します。ただし、配列の中央に挿入する場合は、その要素の後にすべての要素をシフトする必要があるため、その場合の挿入の複雑さは配列のO(n)
です。末尾に追加すると、配列がいっぱいになった場合に配列のサイズを変更する必要がある場合も割引されます。
リンクリストの場合、リストを走査して中間の挿入を行う必要があるため、O(n)
です。ただし、要素を下にシフトする必要はありません。
ウィキペディアには、これに関するニースチャートがあります。 http://en.wikipedia.org/wiki/Linked_list#Linked_lists_vs._dynamic_arrays
Linked list Array Dynamic array Balanced tree
Indexing Θ(n) Θ(1) Θ(1) Θ(log n)
Insert/delete at beginning Θ(1) N/A Θ(n) Θ(log n)
Insert/delete at end Θ(1) N/A Θ(1) amortized Θ(log n)
Insert/delete in middle search time
+ Θ(1) N/A Θ(n) Θ(log n)
Wasted space (average) Θ(n) 0 Θ(n)[2] Θ(n)
挿入ポイントについてすでに知っている挿入について話していると仮定します。つまり、正しい位置を見つけるためにリストの走査を考慮していません。
配列への挿入は、既存の値をシフトする必要があるため、挿入する場所によって異なります。最悪の場合(配列[0]に挿入)はO(x)です。
リストへの挿入はO(1)です。これは、隣接するアイテムの次/前のポインターのみを変更する必要があるためです。
どの文献を参照していますか?配列のサイズは、配列の作成時に決定され、その後は変更されません。本当に挿入できるのは、アレイの最後にある空きスロットのみです。他のタイプの挿入ではサイズ変更が必要になる場合があり、これはO(1)
ではありません。リンクリストのサイズは実装に依存しますが、少なくともすべての要素を格納するのに十分な大きさでなければなりません。要素はリストのどこにでも挿入でき、適切なインデックスを見つけるには走査が必要です。
私が想像する配列の挿入は遅いです。確かに、リンクリストを反復する必要がありますが、配列に挿入するにはメモリの割り当て、保存、割り当て解除を行う必要があります。