1. ホーム
  2. data-structures

[解決済み] なぜバイナリサーチツリーでHashtableを実装するのか?

2022-03-04 05:48:02

質問

Hashtableを配列で実装する場合、配列の定数時間インデックスを引き継ぐことになります。バイナリサーチツリーはO(logn)で検索できるので、Hashtableを実装する理由は何でしょうか?バイナリサーチツリーを直接使うのではだめなのでしょうか?

どのように解決するのですか?

要素に 合計順位 (i.e. "greater than" and "less than" is not be defined for all pairs or it is not consistent between elements), you cannot compare all pairs, thus you can't use a BST directly, but nothing's stoping the BST by the hash value - since this is an integral value, it obviously have a total order (although you would still need to the BST of.), you can not be connected to the BST in the BST by the hash value. 衝突を解決する つまり、同じハッシュ値を持つ要素を処理する方法があります)。

しかし、ハッシュテーブルに対するBSTの最大の利点は、要素が順番に並んでいることです - ハッシュ値で並べると。 要素は任意の順序を持つことになる の代わりに、この利点はもはや適用されないでしょう。

配列の代わりにBSTを使ってハッシュテーブルを実装することを考える理由については、そうなります。

  • 配列のリサイズが必要というデメリットがない - 配列の場合、通常はハッシュ値を配列のサイズで変更し、配列がいっぱいになったらサイズを変更してすべての要素を入れ直しますが、BSTの場合は不変のハッシュ値を直接BSTに挿入すればよいのです。

    これは、個々の操作に一定時間以上かからないようにしたい場合(配列のサイズを変更する必要がある場合は、その可能性が高い)、全体のパフォーマンスは二の次にしたい場合に関連するかもしれませんが、この問題を解決するためのより良い方法があるかもしれません。

  • ハッシュの衝突のリスクを低減 配列のサイズを変更しないので、可能なハッシュの数はかなり大きくなる可能性があります。これにより、ハッシュテーブルの最悪のパフォーマンス(要素の大部分が同じ値にハッシュされること)を得るリスクを減らすことができます。

    実際の最悪のパフォーマンスがどの程度になるかは、衝突をどのように解決しているかによります。これは通常、O(n)の最悪性能のためにリンクリストを使用して行われます。しかし、BSTを用いてもO(log n)の性能を達成することができます(下記で行われているように)。 Javaによるハッシュテーブルの実装 つまり、ハッシュテーブルの配列の各要素が、すべての要素が同じハッシュ値を持つBSTを指しているようにします。

  • メモリ使用量を削減できる可能性がある - 配列の場合、どうしても空のインデックスが発生してしまいますが、BSTの場合、そのようなインデックスが存在する必要がありません。しかし、BSTを使えば、このようなインデックスが不要になります。

    もし、あまり一般的ではない 配列ベースのBST実装 しかし、これは単純なメモリコピーであり、更新されたハッシュですべての要素を再挿入する必要はありません。

    典型的なポインタベースのBST実装を使用する場合、ポインタの追加コストは、配列に空のインデックスがいくつかあることのコストを上回るように見えます(配列が特にまばらでなければ、どのみちハッシュテーブルにとっては悪い兆候となる傾向があります)。

しかし、個人的にこのようなことが行われたという話を聞いたことがないので、おそらく、期待されるO(1)からO(log n)への演算コストの増加に見合うメリットがないのでしょう。

一般的には、BSTを直接使うか(ハッシュ値なし)、ハッシュテーブルを使うか(配列あり)を選択することになります。