B木(びーき、英:B-tree)は、計算機科学におけるデータ構造、特に木構造の一つ。ブロック単位のランダムアクセスが可能な補助記憶装置(ハードディスクドライブなど)上に木構造を実装するのに適した構造として知られる。
実システムでも多用されており、データベース管理システムの多くはB木による索引を実装している(B木の改良型または亜種であるB+木やB*木を使うことが多い)。
構造
多分岐の平衡木(バランス木)である。1 ノードから最大 m 個の枝が出るとき、これをオーダー m のB木という。後述する手順に従って操作すると、根と葉を除く「内部ノード」は最低でも m /2 の枝を持つことを保証できる[2]。
各ノードは、枝の数 - 1 のキーを持つ。枝1 ~ 枝m と キー1 ~ キーm -1 を持つとき、枝i には キーi -1 より大きく キーi より小さいキーだけを保持する(キーの重複を許す場合はどちらかに等号をつける)。
葉ノードの定義は文献によって違いが見られる。木の終端をヌルポインタのような特殊な値で表す場合、枝がすべて終端記号となっているノードを葉とする[3]。これに対して一部の文献では、終端を表すためにキーが0個のノードを連結し、このノードを葉と定義している。すなわち、後者の定義における葉ノードの親が、前者の定義における葉ノードとなる。後者の定義をとる文献では「葉ノードはキーを持たない」ということになる。以下の記述では、前者の定義に従うものとする。
ノードはページと呼ばれることもある[2]。特にハードディスクドライブなどの外部記憶装置を使ってB木を実現する場合によく見られる。この場合、各ノード(ページ)のサイズが、外部記憶装置のブロックサイズの整数倍になるようにオーダーを調整することが多い。
B木の中でも特に、オーダー3のものを2-3木、オーダー4のものを2-3-4木と呼ぶ。
操作
検索
実装例を以下に示す。ここでは簡単のため、ノードの中を探索するのに線形探索を使っているが、ノードに含まれるキーの数が多い場合には二分探索を使うことで高速化できる可能性がある。
- 根を対象ノードとして検索を開始する
- 対象ノードが存在しない場合は検索値が木に登録されていないものとして終了
- i = 1
- キーi が存在しないか、検索値 < キーi の場合、枝i が指すノードを対象として2へ
- 検索値 = キーi の場合、検索成功として終了
- i = i + 1 として4へ
挿入
検索の処理を行うことで、挿入しようとする値が木のどこに位置するべきかがわかる。まだ登録されていない値を検索した場合、処理は必ず葉ノードまで達する。すなわち、挿入処理は常に葉ノードを対象として開始される。ノードにまだ新たなキーを登録する余地がある場合、キーを追加して挿入処理は終了する[3]。
問題は、対象となるノードが既に許容できる最大数のキーを持っている場合である。この場合、ノードの分割処理を行う。分割が必要なノードからキーをひとつ選択し(通常、大小順で中央の値を選択する)、このキーより小さいキーだけを含むノードと、より大きいキーだけを含むノードに分割する。分割の基準となったキーは、親のノードに移動する[3]。
ここで、親ノードに対してキーを追加している[3]。親ノードでキーの最大数を越えた場合は、根に向かって順に分割処理を適用していく[3]。根まで到達して根が分割された場合は、木の高さが1段増加することになる。分割直後の新しい根は、キーを1個と枝を2個だけ持っている。
脚注
参考文献
関連項目
外部リンク
ウィキメディア・コモンズには、
B木に関連するカテゴリがあります。