Radix tree
Radix tree(基数木)はIPアドレスのLongest prefix matching(最長一致)などに使われる二分探索木です。 このエージでは,Radix treeへのノードの挿入、削除、検索アルゴリズムを解説します。 実装はgithub repositoryで公開しています。
Example
具体的なアルゴリズムの説明の前に,以下の5つのエントリを使ってRadix treeの例を見ましょう。
ID | Prefix | Next hop |
---|---|---|
P1 | 01* | N1 |
P2 | 101* | N2 |
P3 | * | N3 |
P4 | 10110 | N4 |
P5 | 10011 | N5 |
以下の図は,上記の5エントリのRadix treeを図示したものです。 Radix treeはキーの各1ビットが二分木の左右の枝に対応しています。 Radix treeでは,それぞれのノードの深さがプレフィックス長+1になるようにノードが配置されています。
検索
検索アルゴリズムは単純に二分木をキーの各ビットに従って辿るだけです。
深さd
から深さd+1
への探索は,キーのd
ビット目の値(0
または1
)により実行されます。
0
であれば左分木,1
であれば右分木を探索します。
例えば,上図の木に対して10101
というキーで探索する場合は,
- キーの最上位ビット(
=1
)を確認し,右の枝に進みます(ノードa
からノードd
) - 次にキーの第2ビット(
=0
)を確認し,左の枝に進みます(ノードd
からノードe
) - 次にキーの第3ビット(
=1
)を確認し,右の枝に進みます(ノードe
からノードi
) - 次にキーの第4ビット(
=0
)を確認し,左の枝に進みます - 左の枝は空のノード(null)なので,親ノードのうち値の存在するノードを逆探索します。
この例ではノード
i
が該当します。 このようにして,10101
に対するLongest prefix matchingの結果として,ノードP2
が得られます。
挿入
ノードの挿入は非常に単純です。 挿入されるノードの位置は深さがプレフィックス長+1であるので,探索と同じ手順で挿入場所を探すことができます。 挿入場所の探索中に空のノードに到達した場合は,値のないノード(例図中の灰色の円)を挿入します。
例えば,以下の図のようにP1, P2, P3, P4が既に挿入された状態で,P5を挿入する例を考えます。
挿入場所の深さはプレフィックス長+1なので,P5
は深さ6
に挿入されます。
検索アルゴリズムと同じ手順で挿入場所を探索します。
この例では,深さ3から4への探索で空のノードに到達するため,値のないノード(灰色の円)を追加します。
このようにして,下図のようにP5が挿入できます。
削除
Radix treeからのノードの削除も単純です。 単純にプレフィックス情報に対応するノードの値を削除するだけです。 削除するノードの子ノードが空の場合は,再帰的に子ノードおよび値のない親ノードを削除できます。
例えば,上図の5エントリの例からP5を削除する場合を考えます。
まず,ノードh
の値を削除します。するとノードh
は子ノードも値も持たないノードになるので,ノードh
自体を削除できます。
次に,削除したノードh
の親ノードに対しても再帰的にノードの削除を試みます。
ノードg
とノードf
は再帰的にノードを削除すると,子ノードも値も持たないノードになるので,これらのノードは削除されます。