二分探索木/Binary-Search-Tree 削除/Delete c++
ハトムギです。
前回に引き続き、二分探索木について書きます。
今回は、指定したkeyを持つnodeの削除について書きます。
二分探索木とは
探索木の中でももっとも基本的なものが、二分探索木です
簡単に説明するとその名の通り、根から枝が二つに分かれ、また各節点から二つに分かれを繰り返します。
今回は、あるnodeのkeyより値の小さいnodeは左側に、大きいnodeは右側にくるように実装しました。
各nodeは、key, 親、左の子、右の子をメンバにもつ構造体により実装できます。
二分探索木・削除
void del(node *u, int k)
まず、kをkeyにもつnodeを探索します。
また、消したいnodeが親の左の子か右の子かをrorl2保存しておきましょう。
つぎに、消したいnodeが持っている子の数で場合分けをします。
子を持たない場合 del0( node *u, int k, int rorl)
方針は、親からのポインタをNULLにし、子から親を指すポインタもNULLにするだけです。
子を一つ持つ場合 del1( node *u, int k, int rorl)
方針は、
消したいnodeの子が左であるか右であるかで場合分けをする。
次に、消したいnodeの子の親を指すポインタを消したいnodeの親を指すポインタにする。
また、消したいnodeが左の子か右の子か場合分けする。
次に、消したいnodeの親の子を指すポインタを消したいnodeの子を指すポインタにする。
最後に消したいnodeの親、子を指すポインタをNULLにする。
子を二つ持つ場合 del2 ( node*u, int k, int rorl)
子を二つ持つ場合が一番難しいです。
方針としは、消したいnodeの次節点nodeのkeyを消したいnodeにコピーして、次節点nodeを削除します。
ここで、次節点とは中間順巡回で消したいnodeの次に得られる節点のことです。
次節点を見つけられたら、次節点nodeがもつ子の数で場合分けをして、del0,del1,del2,を呼び出したらできます。
次節点を見つける。node * getsuc(node*u)
u の次節点を見つけて、その節点へのポインタを返す関数を考えます。
u が右の子を持っている場合、右の子から派生してくる部分木のなかで、最小のkeyを持つnodeが次節点になります。
最小のkeyは今回の木の構造が、左の子は親より小さいkeyを持ち、右の子は親より大きいkeyを持つので左の子をたどっていけば求められます。
uが右の子を持たない場合、uの親を遡っていき、初めて左の子になっているnodeの親がuの次節点になります。
ここで、新たに消したいnodeができたので、その子の数で場合分けしてそれぞれ関数を呼び出します。