38

標準の二分探索木とその操作を完全に理解するのは非常に簡単です。その理解のおかげで、挿入、削除、検索操作の実装を覚える必要さえありません。

私は現在赤黒木を学んでおり、木のバランスを保つためのその特性を理解しています。しかし、その挿入と削除の手順を理解するのは非常に難しいと感じています。

新しいノードを挿入するときは、ノードを赤でマークすることを理解しています (赤黒木の法則をあまり破らないようにするには、赤が最善であるため)。新しい赤いノードは、「連続した赤いノードの法則」にまだ違反している可能性があります。次に、次の方法で修正します。

  1. 赤の場合は叔父の色を確認し、親と叔父を黒としてマークし、祖父母に移動します。

  2. 右の子の場合、親を左回転

  3. 親を黒、祖父母を赤としてマークし、祖父母を右回転させます。

完了 (基本的には上記のように)。

上記のように赤黒木の挿し込みを記載している箇所が多いです。彼らはただそれを行う方法を教えてくれます。しかし、なぜこれらの手順でツリーを修正できるのでしょうか? なぜ最初に左に回転し、次に右に回転するのですか?

CLRSよりも明確に、なぜ私にもっと明確に説明できますか? 回転の魔法とは?

1年も経てば、本を読まなくても自分で赤黒木を実装できるようになるので、本当に理解したいと思っています。

ありがとう

4

7 に答える 7

19

受け入れられた回答で言及されている本にアクセスできないこのスレッドを読んでいる他の人の利益のために、ここに私が受け入れられる説明的な回答になることを願っています。

回転すると、ツリーは色を変更する基準を満たす状態になります (子ノードには赤いおじがあります)。主な違いは 2 つあります。

  • どのノードが「子」で、どのノードが「叔父」であるかが変更されました。
  • 親と叔父を黒に、祖父母を赤に変更する代わりに、親を赤に、祖父母を黒に変更します。

子ノードに赤い叔父がいない場合、叔父ノードがすでに黒の場合、親を黒にすると、祖父母の片側だけで黒の高さが 1 増加するため、回転する必要があります。これは、赤黒木の高さ不変の性質に違反し、木のバランスを崩します。

次に、回転によってツリーがどのように変換されるかを見てみましょう。これにより、赤の叔父を持つ子ノードが作成され、色の変更を使用できるようになります。それを完全に理解するためにこれを描くことをお勧めします。

  • x を赤の親を持つ現在の赤のノードとします。
  • 回転前に p を x の赤の親とします (親が黒の場合は、既に完了しています)。
  • y を回転前の x の黒の叔父とします (叔父が赤の場合、回転は必要ありません。親と叔父を黒に、祖父母を赤に変更するだけです)。
  • 回転前の x の黒の祖父母を g とします (親が赤なので、祖父母は黒でなければなりません。そうでなければ、これはそもそも赤黒木ではありませんでした。)
  • 左-左 (LL) または右-右 (RR) ケースの場合 (つまり、x が p の左の子で、p が g の左の子である、または x が p の右の子で、p が右の子である) g の子)、1 回回転した後 (LL の場合は右、RR の場合は左)、y は子になり、x はその叔父になります。x は赤いおじなので、これで色を変更できるケースができました。したがって、子の親 (子は現在 y であるため、その親は g) を赤に、子の祖父母 (現在は p) を黒に色変更します。
  • LR (x が左の子、または p で p が g の右の子) または RL の場合 (x が p の右の子で、p が g の左の子) の場合、2 回回転した後 (右からLR の場合は左、RL の場合は左から右)、y は子になり、p はその叔父になります。p は赤いおじさんなので、再び色を変更できる場合があります。したがって、親 (子は現在 y であるため、その親は g) を赤に、子の祖父母 (現在は x) を黒に色変更します。

回転と色の変更の前に、A 側 (左または右) に 2 つの赤いノードと 0 つの黒いノード、B 側 (サイド A の反対側) に 0 つの赤いノードと 1 つの黒いノードを持つ黒い祖父母がありました。回転と色の変更後、A 側に 1 つの赤いノードと 0 つの黒いノードがあり、B 側に 1 つの赤いノードと 1 つの黒いノードを持つ黒い祖父母があります。サブツリーの黒の高さを増やさずに祖父母。

それが回転の魔法です。これにより、黒の高さを変更せずに余分な赤いノードを別のブランチに移動でき、二分探索木のソートされたトラバーサル プロパティを保持できます。

于 2013-02-22T02:20:57.120 に答える
5

ロジックはかなり単純です。zが赤で、zの親が赤であると仮定します。zの叔父が赤の場合は、手順1を実行して、(1)親がルートになるまで問題のあるノードを上にプッシュします。次に、ルートを黒でマークします。完了または(2)zの叔父は黒です。

(2)(a)zがその親の左の子である場合、BSTのすべてのプロパティが満たされるため、ステップ3が最後のステップになります。終わり。または(b)zがその親の右の子である。ステップ2は、問題をケース(a)に変換します。次に、ステップ3を実行します。終わり。

したがって、論理は、ケース(1)と(2a)のどちらか早い方に到達しようとすることです。これらは、私たちが解決策を知っている状況です。

于 2012-09-27T00:15:05.393 に答える
3

任意の 2-4 (2-3-4) ツリーを赤黒ツリーに変換できます。また、2 ~ 4 ツリーの理解ははるかに簡単です。2 ~ 4 個のツリーで挿入と削除の操作を実行するだけであれば、同じことを行うためにルールを覚える必要はないと感じるでしょう。さまざまな挿入と削除のシナリオに対処するためのソリューションを考え出すことができる、明確で単純なロジックが表示されます。

2 ~ 4 本の木を明確に理解したら、赤黒木を扱うときはいつでも、この赤黒木を 2 ~ 4 本の木に頭の中でマッピングして、自分でロジックを考え出すことができます。

以下のビデオは、2 ~ 4 本の木、赤黒木、および 2 ~ 4 本の木から赤黒木へのマッピングを理解するのに非常に役立ちます。これらのビデオを見ることをお勧めします。

1) 2 ~ 4 本の木の場合: http://www.youtube.com/watch?v=JZhdUb5F7oY&list=PLBF3763AF2E1C572F&index=13

2) 赤黒木の場合 : http://www.youtube.com/watch?v=JRsN4Oz36QU&list=PLBF3763AF2E1C572F&index=14

それぞれ1時間の動画ですが、見る価値はあると思いました。

于 2014-10-22T07:10:20.867 に答える
2

私の(現在削除された)コメントを無視してください-岡崎のコードが役立つと思います。本 (「純粋関数型データ構造」) をお持ちの場合は、26 ページのテキストと図 3.5 (見開き、27 ページ) をご覧ください。それよりも明確にするのは難しいです。

残念ながら、オンラインで入手できる論文にはその部分がありません。

図は重要なのでコピーしませんが、すべての異なるケースが基本的に同じものであることを示しており、それを理解するための非常に単純な ML コードを示しています。

【更新】amazonで見れるようです。書籍のページに移動し、画像の上にマウスを置き、検索ボックスに「red black」と入力します。25ページと26ページを含む結果が得られますが、それらを見るにはログオンする必要があります(明らかに、ログインして確認していません)。

于 2012-02-28T00:01:54.317 に答える
-1

おそらく、左寄りの赤黒い木から始める価値があります。それらは、興味深い単純化された実装を提供します。

于 2012-09-27T05:49:36.747 に答える
-2

あなたは本当に3つのケースについて良い結論を出しています。

RB-Tree に挿入した後、もしあれば解決すべき主な問題が残っていました。2つの連続した赤いノードがあります!! そのルールに違反せずに2つの連続した赤いノードが消えるようにするにはどうすればよいですか(すべてのパスに同じ数の黒いノードがあります)、2つのノードが表示され、3つの周回しか存在しません...

申し訳ありませんが、アルゴリズム入門のテキストブックをご覧いただけます。

誰もあなたが rb-tree について考えるのを助けることはできません。彼らは重要なポイントでのみあなたを導くことができます。

于 2015-01-21T10:37:30.480 に答える