web-dev-qa-db-ja.com

ハッシュマップルックアップがO(1)つまり一定時間ですか?

Javaパースペクティブから見ると、ハッシュマップのルックアップには一定の時間がかかると言うことができます。しかし、内部実装はどうでしょうか。ハッシュマップの検索には一定の時間がかかると言うのはなぜですか?.

31
genonymous

使用されているハッシュ関数に関する適切な仮定の下では、ハッシュテーブルのルックアップにはexpected O(1) time(標準のハッシュを使用していると仮定すると)これは、平均であり、ハッシュテーブルがルックアップを実行するために行う作業量は、せいぜい一定であることを意味します。

直感的に、「良い」ハッシュ関数を持っている場合、ハッシュテーブル全体に要素がほぼ均等に分散されることが予想されます。つまり、各バケットの要素の数は、要素の数を数で割った値に近くなります。バケットの。ハッシュテーブルの実装がこの数を低く保つ(たとえば、バケットに対する要素の比率が一定の定数を超えるたびにバケットを追加することにより)場合、実行される予想される作業量は、どのバケットを選択するかのベースライン量になりますスキャンしてから、そこにある要素を見て「あまり多くない」作業を行う必要があります。なぜなら、そのバケットには一定数の要素しか存在しないためです。

これは、ハッシュテーブルにguaranteed O(1)の動作があることを意味するものではありません。実際、最悪の場合、ハッシュスキームは縮退し、すべての要素が終了します。最悪の場合、ルックアップに時間Θ(n)がかかるため、適切なハッシュ関数を設計することが重要です。

詳細については、アルゴリズムの教科書を読んで、ハッシュテーブルが非常に効率的にルックアップをサポートする理由の正式な導出を参照することをお勧めします。これは通常、アルゴリズムとデータ構造に関する典型的な大学のコースの一部として含まれており、オンラインで多くの優れたリソースがあります。

おもしろい事実:最悪の場合要素のルックアップ時間がO(1)である特定のタイプのハッシュテーブル(カッコウハッシュテーブル、動的完全ハッシュテーブル)があります。これらのハッシュテーブルは、各要素がいくつかの固定位置のうちの1つにしか存在できないことを保証することで機能します。

お役に立てれば!

34
templatetypedef

キーはドキュメントの次のステートメントにあります。

HashMapインスタンスに多くのマッピングを保存する場合、十分な容量で作成すると、テーブルを拡張するために必要に応じて自動再ハッシュを実行するよりも効率的にマッピングを保存できます。

そして

負荷率とは、ハッシュテーブルの容量が自動的に増加する前に、ハッシュテーブルがどれだけいっぱいになるかを示す尺度です。ハッシュテーブルのエントリ数が負荷係数と現在の容量の積を超えると、ハッシュテーブルが再ハッシュされます(つまり、内部データ構造が再構築されます)。これにより、ハッシュテーブルのバケット数は約2倍になります。

http://docs.Oracle.com/javase/6/docs/api/Java/util/HashMap.html

負荷係数を超えた場合、内部バケット構造は実際に再構築され、償却原価ofgetおよびputはO( 1)。

内部構造が再構築された場合、O(N)になる可能性が高いパフォーマンスの低下が生じるため、かなり多くのgetおよびputは、償却原価が近づく前に必要になる場合がありますO(1)再びそのため、スペースを無駄にしたり、内部構造の回避可能な再構築を引き起こしたりしないように、初期容量と負荷係数を適切に計画します。

7
Eric J.

Templatetypedefのコメントもフォローアップするには:

ハッシュテーブルの一定時間実装は、特定の要素がバケットに存在するかどうかを示すブール配列リストを実装できるハッシュマップにすることができます。ただし、ハッシュマップのリンクリストを実装している場合、最悪の場合、すべてのバケットを通過し、リストの最後を通過する必要があります。

0
jim-zed-li