関連リンク: B木のすごく簡単な実例   おすすめリンク: Stockham FFT 入門

B+ Tree by Java -- B+木の実例

 B+木(B+ Tree)は B木 を変形し、 シーケンシャルアクセスの性能などを改善した多分探索木です。 データベースやファイルシステムを実装する場合、 B木そのものより、このB+木が使われることが多いようです。

 このページではB+木の実装を紹介します。 しかし説明の詳細はB木と重複することが多いので省略します。 ですので、このページを読む前に、 必ず B木のページ を理解してください。 まず、具体的にB+木の例を見てみましょう。以下のようになります。

図1. B+木の例

 B+木は探索木として見ると少し不自然な形をしています。 普通の探索木では、目標のキーが見つかればそこで探索を打ち切りますが、 B+木では、目標のキーが見つかった後も、最下層に到達するまで探索を続けます。 例えば、図1.で説明すると、 根(root)の4から左部分木を探索するとすぐ2が見つかります。 2を探していたのなら、ここで探索を打ち切ればいいわけですが、 B+木の場合、探索を続けて右部分木を探し、 さらにその左部分木を探して最下層の2にたどり着きます。つまり、 キー \(x\) の右部分木の最小値として再びキー \(x\) が現れるという構造をしています。

 このため、B+木の最下層には、登録されているキーが全て現れる事になります。 そして、この最下層のキーにのみ値が対応しています。 丸で表したのが値です。また、 矢印で示したリンクが最下層のノード間に張られています。 こういう構造にすると、値をシーケンシャルにアクセスしたい場合、 最下層のノードだけを効率的にアクセスすることができます。

 では、B木の挿入処理とB+木の挿入処理を比較して見ましょう。 それぞれのソースコードから挿入の部分を抜き出すと以下のようになります。


 顕著な違いは、検索しているキーと一致するキーが見つかった場合の処理です。 B木では一致するキーが見つかると、そこに値を上書きして探索を打ち切るのに対して、 B+木では、一致するキーをスルーして右部分木に対する探索を続行します。

 次にノードを分割する split 処理を見て見ましょう。 B+木では内部ノードでの処理と最下層のノードでの処理が微妙に違います。 内部ノードはほぼB木の処理と同じですが、最下層のノード処理が違います。 ここでは、内部ノードでの split と最下層のノードでの split の違いを示します。


 最下層のノードでの split の最後の return の部分が特徴的です。 右部分木の最小値を削除せず、そのまま上位の木に送り出しています。 この処理があるため、B+木では、 キー \(x\) の右部分木の最小値として再びキー \(x\) が現れることになります。

 最後に、B+木のパフォーマンスについて少し触れておきます。 理由はよくわかりませんが、B+木の検索・挿入・削除のパフォーマンスは、 B木より優れています。シーケンシャルアクセスの改善のみならず、 全体のパフォーマンスの意味でもB+木を使う意義があるようです。

 それでは、B+木の実装の全体を示します。以下のようになります。


関連リンク: B木のすごく簡単な実例   おすすめリンク: Stockham FFT 入門