セット交差点のデータ構造?


19

次の操作をサポートするセットの集合を保持するデータ構造はありますか?準線形の実行時間はありがたいですか?

  1. 空のセットを初期化します。
  2. セットに要素を追加します。
  3. 2つのセットを指定して、それらが交差するかどうかを報告します。

1
これは非常に一般的な質問です。なぜなら、どのデータ構造も有限ドメインでのこれらの操作をサポートできるからです。もう少し具体的に教えていただけますか?例えば。あなたが必要なものの複雑さ、あなたは喜んなど一連の操作を取得するために犠牲にするものです
バルトシュPrzybylskiの

回答:


12

各セットは他のセットが存在するかの記録を維持し、あなたが全体の持っている場合はセット、簡単に(収集のために任意のデータ構造を変えることができます例えば、二分探索木をなど、あなたがの検索を持つことができるものに)時間O log s の2セットの交点の要素。s>0O(logs)

  • 各セットには、完全に順序付けられたセットの一意の識別子が必要です。セットに明示的に名前を付けると、識別子は単なるインデックスになります。S1,S2,

  • セットの「レジストリ」を実装する必要があります。定義したすべてのセットのコレクションを保持するデータ構造。レジストリは、検索ツリーデータ構造として実装する必要があります。これにより、検索を簡単に(たとえば  、セットを削除する場合)、セットの線形時間走査が可能になります。

  • 各セットは、他の各セットの「インデックス」も保持します。それらのコピーではなく、他のセットのラベルによってインデックス付けされたデータ構造です。このインデックスは、各セットのために、維持するために使用されるS k個の要素のすべてのバイナリ検索ツリーSのJS K。(2つのセットS jS kは、その検索ツリーの1つのコピーを共有します。)SjSkSjSkSjSk

初期化

セットの初期から成るO 1 操作はその要素のツリー初期化するO S あなたは(レジストリからのコピー)を初期化などの操作を設定するための指標T、およびO S ログS レジストリを走査してTを他の各セットS jのインデックスに追加するときの操作。指標ではT、我々は代表探索木作成T Sのjは = T=O(1)O(s)TO(slogs)TSjTTSj=他のセットS jのインデックスに同じポインタをコピーします。SjSj

セットTへの要素の追加T

いくつかの追加セットにTが時間かかりO ログN Tのここで、いつものように、N T = | T | 。我々のメンバーシップのために、試験のx他のセットの各々におけるS 1S 2...時間かかり、O ログN S 1 + ログN S 2 + O S ログNをxVTO(lognT)nT=|T|xS1,S2,ここで n = | V | はユニバース(または最大セット S j)のサイズであり、 sはレジストリ内のセットの数です。各セットのために S jのような xはSのjは、インサート、 Xセットのインデックスに S JT。このような各セットについて S jを、これがかかり O ログS +のログN Tルックアップする時間を、 S jは

O(lognS1+lognS2+)O(slogn),
n=|V|SjsSjxSjxSjTSjO(logs+lognT)Sj指標でと挿入するX線S JT。すべてのセットS 1S 2...これには時間O s log s + s log n Tがかかります。我々はセット数と仮定した場合S jがはるかに少ない宇宙の大きさよりもV(私たちが思うならば、あるS « nで)、要素の挿入のための総時間は、あるO S ログN TxSjTS1,S2,O(slogs+slognT)SjVsnO(slogn)

xSTxO(lognT)

交差点試験

SjSkSjSkO(logs)SjSkSjSk

エレメント除去

xTTSjTSjO(slognT)nT=|T|

セット削除

SSjO(snT)SjTSjnT=|T|

備考

一定数のセットのみを実装する場合、上記の実行時間は次のように短縮されます。

  • O(1)

  • O(logn)

  • O(1)

  • O(lognT)

  • O(nS)

nnT=|T|T

O(|V|)VSTS


5

最悪の場合でも、線形時間未満でこれを行うことができるデータ構造があります。http://research.microsoft.com/pubs/173795/vldb11intersection.pdf(およびそこにある論文参照)を参照してください。

2つのセットSとTの交差部分が大きく、Sの辞書がある場合、Tの要素をランダムな順序で検索すると、すぐに共通の要素が得られます。最も難しいケースは、交差サイズが0または1の場合です。


3

通常、選択したプログラミング言語は、一意の要素を持つデータ構造をサポートします。一般に、ツリー、ハッシュ、ビットマスクという3つの一般的なアプローチがあります。ツリー要素は比較可能でなければならず、ハッシュ要素はハッシュ可能でなければならず、ビットマスク要素は整数への何らかの変換方法を持たなければなりません。

ツリーセットは、O(log n)への挿入と、最悪の場合のO(n log n)での交差テストをサポートします。

ハッシュセットは、「h」がハッシュアルゴリズムの実行時間であるAmortized O(1 * h)への挿入と、最悪の場合のO(n)での交差テストをサポートします。

通常、ビットマスクセットは、ツリーセットやハッシュセットのようには使用されません。


2
これはまともなスタックオーバーフローの答えになりますが、ここでは、その仕組み理由について詳しく説明します
ラファエル

3

あなたのケースが偽陽性の回答を許可する場合、私は単一のハッシュ関数でブルームフィルターを使用します。

次のように実装できます。

空のセットを初期化する

  • Bnn

セットに要素を追加します。

  • B[hash(element)]=1

2つのセット(B1、B2)が与えられた場合、それらが交差するかどうかを報告します。

  • B1 AND B2 = 0

複雑

  • nO(1)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.