互いに素な集合データ構造は、集合Sの分割を表すためのデータ構造です。まず、それぞれが独自のグループに属する要素の集合Sから始めます。例えば:
{1} {2} {3} {4} {5} {6}
素集合データ構造に対する1つの演算は、与えられた要素を含む2つの集合を結合する和集合演算です。たとえば、1と2を結合すると、パーティションが返されます。
{1, 2} {3} {4} {5} {6}
3と5を結合すると
{1, 2}, {3, 5}, {4}, {6}
ここで、1と3を結合すると、パーティションが生成されます
{1, 2, 3, 5}, {4}, {6}
検索操作は、特定の要素がどのセットに属しているかを示します。通常、これは、findが属する要素の代表的な要素を返すことによって行われます。これは通常、次のように行われます。
find(x) == find(y) if and only if x and y are in the same set.
たとえば、find(1)は2を返す可能性があるため、find(2)= 2、find(3)= 2、find(5)=2です。
素集合データ構造は、クラスカルの最小スパニングツリーアルゴリズムのサブルーチンとしてよく使用されます。これは、グラフ内の2つのノードが接続されているかどうかを非常に高速にチェックし、2つの接続されたコンポーネントのすべてのノードが接続されていることを簡単にマークできるためです。エッジが追加されると互いに。ランクごとの和集合とパス圧縮を使用した素集合フォレストの実装を使用すると、素集合フォレストでのn回の演算をO(nα(n))時間で実行できます。ここで、α(n)は逆アッカーマン関数です。非常にゆっくりと成長する関数は、事実上一定です(ユニバースのサイズよりも小さい入力の場合、最大で4つです)。
二項木と二分木について:あなたが求めているのは、多くても2つの子を持つ二分木を使用して、多方向の木である二項木をどのように表現するかということだと思います。すべての二項ツリーが二分木であるとは限らないため、適切なエンコーディングを使用する必要があります。
これを行う1つの方法は、左子右兄弟表現と呼ばれるものを使用することです。これは、次の設定に従って、多分木を二分木として表します。
- 各ノードの左の子は、ノードの最初の子を指します。
- 各ノードの右の子は、次の兄弟(同じ親を持つ同じレイヤー内のノード)を指します。
たとえば、次の二項ツリーがあるとします。
a
/ | \
b c d
/| |
e f g
|
h
左子右兄弟表現は次のようになります
a
/
b
/ \
e c
\ / \
f g d
/
h
ちなみに、これを二項ツリーで行うと、二項ツリーは、次のプロパティを持つ二分ツリーである、半順序半ツリーと呼ばれるものとして表現されることになります。
- ツリー内のすべてのノードは、左側のサブツリー内のすべてのノード以上です(または、これが最小ヒープか最大ヒープかによって異なります)。
- ルートノードには正しい子がありません。
これらの定義は、二項ツリーがヒープ順に並べられてから、左子の右兄弟表現に変換されるという事実に基づいています。この表現を使用すると、二項ツリーにリンクするのが非常に高速になります。それは読者の練習問題として残しておきます。:-)
お役に立てれば!