web-dev-qa-db-ja.com

個別の連鎖にバイナリ検索ツリーを使用してハッシュテーブルを高速化することは可能ですか?

バイナリサーチツリーを使用してハッシュテーブルを実装し、個別チェーンプロセスの検索の複雑さをO(n)(リンクリストを使用)からO(log n)に(BSTを使用)に削減します。 。これを行うことはできますか?はいの場合、どのようにして行うのですか?ソリューションが段階的なロジックの実装であるかどうかを理解する方が簡単でしょう。

ハッシュテーブルの検索時間を短縮したい(個別のチェーンを使用して構築)が、同時に挿入時間を長くしたくない。私のプロジェクトでは、衝突を減らすためにハッシュ関数を変更できません。ただし、スケーラビリティのため、衝突が発生しています。私は回避策を見つけようとしているので、衝突が発生した場合に最適なアクセスと挿入時間で何らかの方法で作業できます...つまり、アルゴリズム全体を再構築するよりも、現在の状態を管理するためです。パンしない場合は、再構築する必要があります。だから何かアイデア?

11
Aviral

あなたが求めていることは、あなたの制約があれば可能です。

分析

ハッシュテーブルの強みは、高速な検索と挿入の速度です。その速度を得るには、テーブル内の順序の類似をすべて無視する必要があります。つまり、エントリはすべてごちゃ混ぜになっています。トラバーサルはO(n)ですが、ハッシュテーブルが十分に大きく、テーブルに格納されているオブジェクトが高品質のハッシュアルゴリズムを使用してハッシュされていると想定すると、リストはテーブルエントリとして使用できます。

二分探索木(BST)はO(log2 n)。また、格納する要素にも制限を課します。要素を順序付ける方法が必要です。ツリーに2つの要素[〜#〜] a [〜#〜]および[〜#〜] b [〜#〜]が格納されているとすると、 [〜#〜] a [〜#〜][〜#〜] b [〜#〜]の前にあるか、同等の順序であるかを確認します。

ハッシュテーブルにはそのような制限はありません。ハッシュテーブルの要素には2つのプロパティが必要です。まず、それらが同等かどうかを判断する方法がなければなりません。次に、確定的ハッシュコードを計算する方法が必要です。順序は必須ではありません。

ハッシュテーブルの要素に順序がある場合は、BSTをハッシュテーブルエントリとして使用して、同じハッシュコード(衝突)を持つオブジェクトを保持できます。ただし、BSTにO(log2 n)ルックアップと挿入。つまり、構造全体(ハッシュテーブルとBST)の最悪のケースは、リストをテーブルエントリとして使用するよりも技術的に優れています。 BSTの実装によっては、リストよりも多くのストレージが必要になりますが、それ以上ではない可能性があります。

通常、BSTのオーバーヘッドと動作はテーブルに何ももたらさないことに注意してください実際の状況ではハッシュテーブルバケットとして、リストの理論的なパフォーマンスの低下は許容できる理由です。つまり、ハッシュテーブルは、各リスト(バケット)に配置するアイテムの数を減らすことで、リストの弱点を補っています。 ただし:問題は、ハッシュテーブルcannotのサイズが増加することを明確に示しており、衝突は、ハッシュテーブルで一般的なものより頻繁です。

実装

正直なところ、それは本当に必要ではなく、とにかく言語を指定しなかったので、ここにはコードを入れません。

言語の標準ライブラリに含まれている標準ハッシュテーブルを新しいクラスにコピーし、テーブルバケットの種類をリストからツリーに変更するだけです。言語とその標準ライブラリによっては、これは非常に簡単なことかもしれません。

通常、私はこのようなコードのコピーアンドペーストを推奨しません。ただし、これは、戦闘テスト済みのデータ構造veryをすばやく取得する簡単な方法です。

11
user22815

ハッシュテーブルで衝突処理にバイナリツリーを使用することは、単に可能であるだけではありません。

Walter BrightDプログラミング言語 の発明者として最もよく知られていますが、 DMDScript と呼ばれるECMAScriptバリアントも作成しました。以前、DMDScript(またはおそらく祖先-私はDScriptの名前を覚えているようです)の主な主張は、そのハッシュテーブルが多くの類似した言語のハッシュテーブルよりも優れている傾向があるというものでした。理由-バイナリツリーを使用した衝突処理。

私はこれがどこから来たのか正確には覚えていませんが、使用されたツリーは単純なバイナリツリーであり、部分的なバランススキーム(AVLや赤黒などではありません)がありません。ハッシュ衝突の不合理な確率は得られません。バイナリツリーは常に小さいはずです。基本的に、最悪のケースは衝突処理にリンクリストを使用する場合と同じです(ノードごとに1つではなく2つのポインターの料金を支払うことを除く)。ただし、平均的なケースでは、各ハッシュバケット内の検索量が減少します。

7
Steve314