赤黒木
赤黒木は二分探索木であり、すなわち、各ノードのもつ値が
そのノードの右部分木に含まれるノードのもつ値より大きくない
そのノードの左部分木に含まれるノードのもつ値より小さくない
という性質をもつようにつくられる。これによって、木の中から特定の値をさがすことや、すべての値を順番にあたることなどが素早くできるわけである。
ノードの黒深さは、根からそのノードまでの黒ノードの数(すなわち黒祖先の数)と定義される。赤黒木の黒高さは、根から葉までのどの経路にもある黒のノードの数であり、要件5により一定である(代わりに、任意の葉のノードの黒深さとして定義することもできる)。 ノードの黒高さは、そのノードが根とする部分木の黒高さである。この記事では、NILノードの黒高さは0とする。なぜなら、その部分木は図2が示唆するように空であり、その木の高さも0であるからである。
赤黒木(あかくろぎ)は、コンピュータ科学のデータ構造である平衡二分木の一種で、主に連想配列の実装に用いられている。2色木、レッド・ブラック・ツリーともいう。
このデータ構造は1972年のルドルフ・ベイヤー (en:Rudolf Bayer) の発明である"symmetric binary B-trees"が元となっており、赤黒木という名前自体は 1978年にレオニダス・ギッバス (en:Leonidas J. Guibas) とロバート・セジウィック (en:Robert Sedgewick) によって発表された論文による。
赤黒木は、探索、挿入、削除などの操作における最悪時間計算量がO(log n)(nは木の要素数)と短く、複雑ではあるが実用的なデータ構造として知られている。
この日本語版は概要のみの解説であり、具体的なアルゴリズムはwikipedia英語版(Red-black_tree)に掲載されている。
赤黒木は挿入時間、削除時間、探索時間において、最悪のケースを保証する。これはリアルタイムシステムのような時間センシティブなアプリケーションにおいて価値あるのみならず、最悪のケースを保証する他のデータ構造における価値ある部品となっている。 例えば、計算幾何学で用いられる多くのデータ構造は赤黒木をベースとしているし、現行のLinuxカーネルで用いられる CFS (Completely Fair Scheduler)では赤黒木を使用している。
AVL木は O ( log  n ) {\displaystyle {\mathcal {O}}(\log n)} の探索、挿入、削除をサポートする、もう一つのデータ構造である。AVL木は、赤黒木よりも厳密な平衡性を持っているため、挿入や削除は遅くなるが、検索は早くなる。このため、AVL木は一度構築して、再構成する必要のないデータ構造にとっては魅力的である。例えば、言語辞書(または、アセンブラやインタープリタの命令コードのようなプログラム辞書)などのように。
また、赤黒木はAVL木よりも条件が多いため、実装が面倒である。
赤黒木はまた、最も一般的な永続データ構造のひとつであり、関数型言語で特に価値がある。変化後に前のバージョンを保持できるように、連想配列や集合 (プログラミング)を構築するのに使われる。赤黒木の永続バージョンは、各挿入や各削除において O ( log  n ) {\displaystyle {\mathcal {O}}(\log n)} の(時間に加えて)空間を要する。
ケースによってノードに変更があった場合、後の状態の列グループに示される。
次の列の矢印→は、このステップでリバランシングが完了したことを意味する。後の状態の列がちょうど1つのケースとなる場合、そのケースが次のケースとして示され、そうでない場合は疑問符が示される。
ループは挿入ケース1と挿入ケース2の章に含まれ、ケースI2では、Gが新しいカレントノードNになるという意味で、リバランシングの問題が Δ h = 2 {\displaystyle \Delta h=2} レベル高い木にエスカレートされる。そのため、木の修復には最大で h 2 {\displaystyle {\tfrac {h}{2}}} 回の繰り返しが必要になる(ここで h {\displaystyle h} は木の高さ)。エスカレーションの確率は各反復で指数関数的に減少するので、総リバランシングコストは平均で一定であり、実際に償却された定数になる。
ループの本体から、ケースI1は単独で抜け、ケースI4、I6、I5 + I6、I3への終了分岐がある。
回転はI6とI5 + I6の時にループの外側で発生する。したがって、合計で最大2回の回転が発生する。