13. 2 分探索木のためのアルゴリズム 5/5
( 削除 2/3)
3. 着目ノードが削除する対象(以下、削除ノー
ド)の場合
a) 削除ノードが子どもを持たないなら、その
ノードをそのまま削除する。
b) 削除ノードが子どもを一つしかもっていない
場合は、削除ノードを削除してその子どもと
置き換える。
b
c) ( 次ページ )
a
14. 2 分探索木のためのアルゴリズム 5/5
( 削除 3/3)
3. 着目ノードが削除する対象(以下、削除ノー
ド)の場合
c) 削除ノードが子どもを二つ持つ場合
i. 削除ノードの左の子から最大の値を ( 再帰的
に ) 探索する。
ii. i. で探索してきたノード(以下、探索ノード)
を削除対象のノードと置き換えて、削除対象の
ノードを削除する。このとき探索ノードの左の
子を探索ノードの元位置に置き換える
*D
( 最大・最小、左右は逆でも良い )
32. ( 参考 ) Btree のアルゴリズム
( 疑似コード:検索 )
B-Tree-Search(x, k)
i <- 1
while i <= n[x] and k > key_i[x]
do i <- i + 1 // find_location の動作
if i <= n[x] and k = key_i[x]
then return (x, i)
if leaf[x]
then return NIL
else
return B-Tree-Search(c_i[x], k)
33. ( 参考 ) Btree のアルゴリズム
( 疑似コード:挿入 )
B-Tree-Insert(T, k)
r <- root[T]
if n[r] = 2t - 1
then s <- Allocate-Node()
root[T] <- s
leaf[s] <- FALSE
n[s] <- 0
c_1 <- r
B-Tree-Split-Child(s, 1, r)
B-Tree-Insert-Nonfull(s, k)
else B-Tree-Insert-Nonfull(r, k)
34. ( 参考 ) Btree のアルゴリズム
( 疑似コード:飽和してないノードへの挿入 )
B-Tree-Insert-Nonfull(x, k)
i <- n[x] i <- i + 1
if leaf[x] if n[c_i[x]] = 2t - 1
then while i >= 1 and k < key_i[x] then B-Tree-Split-Child(x, i, c_i[x])
do key_i+1[x] <- key_i[x] if k > key_i[x]
i <- i - 1 then i <- i + 1
key_i+1[x] <- k B-Tree-Insert-Nonfull(c_i[x], k)
n[x] <- n[x] + 1
else while i >= 1 and k < key_i[x]
do i <- i - 1
35. ( 参考 ) Btree のアルゴリズム
( 疑似コード:挿入のための子分割 )
B-Tree-Split-Child(x, i, y)
z <- Allocate-Node() n[y] <- t - 1
leaf[z] <- leaf[y] for j <- n[x] + 1 downto i + 1
n[z] <- t - 1 do c_j+1[x] <- cj[x]
for j <- 1 to t - 1 c_i+1 <- z
do key_j[z] <- key_j+t[y] for j <- n[x] downto i
if not leaf[y] do key_j+1[x] <- key_j[x]
then for j <- 1 to t key_i[x] <- key_t[y]
do c_j[z] <- c_j+t[y] n[x] <- n[x] + 1
36. ( 参考 ) Btree のアルゴリズム
( 疑似コード:削除の疑似コード 1/2)
B-Tree-Delete(x, k): 斜体は定義なし
i ← find_location (x, k) else if n[c_i+1[x]] > t-1 // a'.
// 1. then km <- find_min(c_i+1[x])
if exists (key_i[x], k) then key_i[x] = km
if leaf[x] B-Tree-Delete(c_i+1[x], km)
then return delete key_i[x] else // c.
// 2. x が中間ノード // c_i[x] 側にマージ
else Merge-Child (x, c_i[x], c_i+1[x])
if n[c_i[x]] > t-1 // a. B-Tree-Delete (c_i[x], k)
km <- find_max(c_i[x]) else // 3. x にキーがない
key_i[x] = km // ( 次ページ )
B-Tree-Delete(c_i[x], km)
find_location は List::MoreUtils::firstidx を使うと簡単
37. ( 参考 ) Btree のアルゴリズム
( 疑似コード:削除の疑似コード 2/2)
B-Tree-Delete(x, k): 斜体は定義なし
// 3a else
if n[c_i-1[x]] > t-1 then Merge-Child(x,c_i-1[x], c_i[x])
// 右回転
rotate_right (x, c_i[x], c_i-1[x])
// 3b
else if n[c_i+1[x]] > t-1 then
// 左回転
rotate_left (x, c_i[x], c_i+1[x])
else
if c_i+1[x] then
Merge-Child(x,c_i[x], c_i+1[x])