コンピュータサイエンスでは、ハッシュテーブルの挿入、削除、検索の操作はO(1)の複雑さであり、これが最良であると言われています。それで、ハッシュ操作がとても速いのに、なぜ他のデータ構造を使用する必要があるのか疑問に思いました。単純にすべてにハッシュ/ハッシュテーブルを使用できないのはなぜですか?
ハッシュテーブルは、平均して、挿入、取得、および削除に優れた時間計算量を持っています。だが:
Big-Oの複雑さがすべてではありません。 定数係数も非常に重要です。配列インデックスをハッシュキーとして、配列の代わりにハッシュテーブルを使用できます。いずれの場合も、アイテムを取得する時間の複雑さはO(1)です。ただし、定数係数は、配列ではなくハッシュテーブルの方がway高くなります。
メモリ消費量ははるかに高くなる可能性があります。ハッシュテーブルを使用して配列を置き換える場合、これは確かに当てはまります。 (もちろん、配列がスパースの場合、ハッシュテーブルはより少ないメモリを使用する可能性があります。)
キーが特定の範囲内にあるすべての要素を反復処理したり、最大キーまたは最小キーを持つ要素を検索したりするなど、ハッシュテーブルで効率的にサポートされていない操作がいくつかあります。
それはさておき、あなたはdoまだ良い点があります。ハッシュテーブルには、非常に幅広い適切なユースケースがあります。そのため、Luaなどの一部のスクリプト言語の主要な組み込みデータ構造です。
ハッシュを使用して要素を検索することはできますが、最大数をすばやく見つけるなどの目的で使用することはできません。指定された問題にはデータ構造を使用する必要があります。ハッシュはすべての問題を解決できるわけではありません。
HashTable
はすべての答えではありません。ハッシュ関数がキーを適切に分散しない場合、最悪の場合はhashMap
がlinkedList
に変わる可能性があり、最悪の場合、挿入、削除、検索にはO(N)
が必要になります。 。
HashMap
にはかなりのメモリフットプリントがあるため、メモリが時間計算量よりも貴重である場合があり、HashMap
は最良の選択ではない可能性があります。
HashMap
は、範囲クエリまたはプレフィックスクエリの回答ではありません。そのため、ほとんどのデータベースベンダーは、範囲またはプレフィックスクエリのハッシュだけでなく、Btree
によるインデックス作成を実装しています。
HashTable
は一般に参照の局所性が低く、アクセスされるデータがメモリ内でランダムに分散されているように見えます。
スペルチェックなどの特定の文字列処理アプリケーションでは、ハッシュテーブルは、試行、有限オートマトン、またはJudy配列よりも効率が低い場合があります。また、各キーが十分に少ないビット数で表されている場合は、ハッシュテーブルの代わりに、値の配列へのインデックスとしてキーを直接使用できます。この場合、衝突は発生しないことに注意してください。
Web上のハッシュテーブルの潜在的なセキュリティ問題も指摘する必要があります。誰かがハッシュ関数を知っている場合、その人は同じハッシュコードで多数のアイテムを作成することによってサービス拒否攻撃を実行する可能性があります。