2017-03-11 21 views
3

現在、私は私の大学のためのプロジェクトをやっています。既知のデータ構造(配列、リンクリスト、BSTなど)を実装しています。たとえば、私にとって最初のものは配列でした。私は配列の途中に要素を追加する時間を測定しました。(さらに値を移動すると、n = n + 1です。もちろん、これはO(n)です。ここでnは要素の数です。 。アレイと、それ(最後に加える)に要素を追加するの先頭に私は(私はSTLまたはboost::を使用することはできません)2つの、簡単なアルゴリズムを持っている:並べ替えられた配列の複雑な計算

が先頭に追加:

void array::beginning_append(int value) 
{ 
    int *temp = new int[n + 1]; 
    memcpy(temp + 1, table, sizeof(int) * n); 
    n = n + 1; 
    temp[0] = value; 
    delete[] table; 
    table = new int[n]; 
    memcpy(table, temp, sizeof(int) * n); 
    delete[] temp; 
} 

最後に追加:

void array::append(int value) 
{ 
    int *temp = new int[n + 1]; 
    memcpy(temp, table, sizeof(int) * n); 
    temp[n] = value; 
    n = n + 1; 
    delete[] table; 
    table = new int[n]; 
    memcpy(table, temp, sizeof(int) * n); 
    delete[] temp; 
} 

これらはメソッドまたはarrayクラスです。tableおよびnはこのクラスのメンバーです。今ではそれほど違いはないと思いますが、その時代は同じだと思っていました(500000のような要素の数が多いとQueryPerformanceCounterでチェックしました)、私にはO(n)の複雑さが与えられましたが、 O(n)の計算量が必要ですが、最後に要素を追加または削除すると複雑さはO(1)になるため、要素の数に関係なくconstになります。だから、私はアルゴリズムが悪い場合、私は彼らが不必要なものを行う意味、彼らは要素の数に依存している理由です、または私の講師はちょうど間違っていた君たちをお願いしたいと思い

+0

追加するのではなく、前に追加しますか? :) – gsamaras

+0

私はそれをすべきです:D私がコーディングしているとき、私の話す能力、または適切な英語を書く能力が低下するので、私は '始まり 'の代わりに'ベージニング 'を書いています – Frynio

+0

どちらの場合も配列全体を再割り当てしてコピーします。なぜ最後に追加するのが常であるのか理解したいのであれば、_amortized一定時間@ – paddy

答えて

3

どちらの複雑さは、次のとおりです。

O(n)

アレイ全体をコピーしているためです。

複雑度の詳細については、memcpy()hereを参照してください。


ヒント:簡単tableを指しているメモリを解放し、それがtempをポイントすることによって、2番目のコピーをスキップすることができます。そうすれば、二度ではなく一度だけコピーします。しかしながら、全体的な時間の複雑さは変化しない。

例:

void array::prepend(int value) 
{ 
    int *temp = new int[n + 1]; 
    memcpy(temp + 1, table, sizeof(int) * n); 
    n = n + 1; 
    temp[0] = value; 
    delete[] table; 
    table = temp; 
} 

プロチップ:How do you detect/avoid Memory leaks in your (Unmanaged) code?

のHunch:realloc()の巧妙な実装では、新しいアレイにブルートmemcpy()より速く実行する必要があります。その理由は、realloc()が配列全体を新しい場所にコピーすることなく配列を拡大/縮小できれば(これは、単純な連続スペースがない場合に発生する可能性があります)、より高速になります。 realloc()は常にO(1)を意味するわけではありません。

+0

この行があります: 'n = n + 1' – Frynio

+0

申し訳ありません@Frynio、更新されました!素敵な質問BTW;) – gsamaras

+0

ポイントは:あなたはなぜ2回アレイをコピーしますか?ちょうどテーブルポイントの温度を作る – Jack

1

バッファを新しい要素を保持するのに十分な大きさにすると、最後に追加することが可能です(O(1))。通常、再割り当てが行われると、再割り当てをあまり頻繁に行う必要がないため、メモリサイズが現時点で必要以上に増加します。

この場合、再割り当てが発生すると、平均複雑度はO(1)、最悪の複雑度はO(n)になります。

+0

私はテーブルを動的に割り当てる必要があり、サイズは要素の数と同じくらい大きくなければなりません – Frynio

+0

例えばstl 'vector'は' size'と 'capacity'メンバを持ちます、' size'はもちろんです常に正確です。 – alain

+0

['std :: vector :: shrink_to_fit'](http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit) – paddy

関連する問題