(Sub) tree を区間で表す.
Pre order P : \( [r \ (A_{0})(A_{1})] \),
In order I: \( [(B_{0})\ r \ (B_{1})] \)
の形で表せる.ここで, \(r\) は root, \(A_{0}, B_{0}\) は左側の subtree, \(A_{1}, B_{1}\) は右側の subtree. Root \(r\) の入る場所以外は同じ.
\(P\) の方を見れば,root \(r\) の位置はすぐに分かる. ここで, \(I\) における \(r\) の位置を取得すれば, \(I\) を \(r\) で左右に分けて, \(r\) の左右の subtree に対応する区間が分かる. とくに,それぞれの subtree の頂点の個数が分かる.
よって,その個数を \(x,y\) とおけば その \(P\) を \(x,y\) を用いて分割できる. 分割した \(P\) における区間が subtree になるので,これを再帰的に繰り返す. 構成と同時に判定ができる.
実装
再帰関数の戻り値 in int は,
- -1 : 条件を満たさない
- 0 : subtree が empty
- a (>0) : (調べている subtree の root) + 1
としている.
メモ
\(P,I\) の subtree の長さは等しいことをキープしながら遷移するので, 再帰関数の引数は \(P\)における左端, \(I\)における左端, 長さ の 3つで十分. 引数の個数を減らせれば,ミスも少なくなる.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"