# まとめ ### 要点の振り返り - 二分木は「一つを二つに分ける」という分割統治の論理を表す非線形データ構造です。各ノードには値と、左右の子をそれぞれ指す二つのポインタがあります。 - あるノードの左(右)の子とその下のノードが作る木を、そのノードの左(右)部分木と呼びます。 - 関連する用語には、根ノード、葉ノード、レベル、次数、辺、高さ、深さなどがあります。 - 初期化、ノードの挿入・削除の方法は、連結リストと似ています。 - 主な種類には、パーフェクト二分木、完全二分木、全二分木、平衡二分木があります。パーフェクト二分木は最も理想的な状態で、連結リストは退化した最悪の状態です。 - 二分木は配列でも表せます。ノードの値と空の位置をレベル順に並べ、親子のインデックスの対応でポインタを実現します。 - レベル順走査は幅優先探索の一種で、一周ずつ外へ広がるように層ごとに進み、通常はキューで実装します。 - 行きがけ順、通りがけ順、帰りがけ順は深さ優先探索で、行き止まりまで進んでから戻って続ける方法です。通常は再帰で実装します。 - 二分探索木は要素を効率よく探せるデータ構造で、探索、挿入、削除の時間計算量はすべて $O(\log n)$ です。連結リストに退化すると、いずれも $O(n)$ に悪化します。 - AVL 木は平衡二分探索木とも呼ばれ、回転によって、挿入と削除を続けても平衡を保ちます。 - AVL 木の回転には、右回転、左回転、右回転してから左回転、左回転してから右回転があります。挿入や削除の後、下から上へ回転して平衡を取り戻します。 ### Q & A **Q**:ノードが一つだけの二分木では、木の高さも根の深さも $0$ ですか? はい。通常は、通る辺の数で高さと深さを定義するためです。 **Q**:二分木の挿入・削除は複数の操作を組み合わせるとありますが、どういう意味ですか? リソースの子ノードのリソースを解放することと考えてよいですか? 二分探索木を例にすると、削除には三つの場合があり、それぞれで複数のノード操作が必要です。 **Q**:二分木の DFS には、なぜ行きがけ順、通りがけ順、帰りがけ順があり、それぞれ何に使いますか? 配列を順方向や逆方向に走査するのと同様、これらは特定の順序で結果を得るための三つの走査方法です。例えば二分探索木では、`左の子の値 < 根の値 < 右の子の値` が成り立つため、「左 $\rightarrow$ 根 $\rightarrow$ 右」の順で走査すれば、整列済みのノード列を得られます。 **Q**:右回転は不均衡な `node`、`child`、`grand_child` の関係を処理しますが、`node` と親のつながりは更新しなくてよいのですか? 切れてしまいませんか? 再帰の視点から考える必要があります。`right_rotate(root)` は部分木の根を受け取り、最後に `return child` で回転後の根を返します。部分木の根と親の接続は、この関数から戻った後に行うので、右回転の処理範囲には含まれません。 **Q**:C++ で関数を `private` と `public` に分ける基準は何ですか? `height()` は `public`、`updateHeight()` は `private` なのはなぜですか? 主に利用範囲で決めます。クラス内部だけで使うなら `private` にします。例えば `updateHeight()` は挿入や削除の一段階なので、利用者が単独で呼ぶ意味はありません。一方、`height()` は `vector.size()` のように高さを取得するものなので、使えるように `public` にします。 **Q**:入力データから二分探索木をどう構築しますか? 根の選び方は重要ですか? はい。構築方法は、二分探索木のコードの `build_tree()` にあります。通常、入力をソートして中点の要素を根とし、左右の部分木を再帰的に構築します。こうすることで、平衡性をできるだけ高く保てます。 **Q**:Java の文字列比較には、必ず `equals()` を使いますか? Java では、基本データ型の `==` は二つの変数の値が等しいかを比較します。参照型では、二つの方法の仕組みが異なります。 - `==`:二つの変数が同じオブジェクト、つまり同じメモリ位置を指すかを比較します。 - `equals()`:二つのオブジェクトの値が等しいかを比較します。 値を比較するなら `equals()` を使うべきです。ただし、`String a = "hi"; String b = "hi";` で初期化した文字列は文字列定数プールに格納され、同じオブジェクトを指すため、`a == b` でも内容を比較できます。 **Q**:幅優先走査で最下層に到達する直前、キューのノード数は $2^h$ ですか? はい。例えば高さ $h = 2$ のパーフェクト二分木なら、総ノード数は $n = 7$ で、最下層のノード数は $4 = 2^h = (n + 1) / 2$ です。