Files
hello-algo/ja/docs/chapter_tree/summary.md
T
Yudong Jin 7257641e0e Retranslate the complete Japanese online edition from Chinese (#2008)
* Retranslate the complete Japanese online edition from Chinese

* Fit Japanese homepage labels and localize heading permalinks

* Point Japanese contribution instructions to the Japanese preview

* Replace locale conditionals with multilingual UI tables
2026-10-30 02:12:26 +08:00

55 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# まとめ
### 要点の振り返り
- 二分木は「一つを二つに分ける」という分割統治の論理を表す非線形データ構造です。各ノードには値と、左右の子をそれぞれ指す二つのポインタがあります。
- あるノードの左(右)の子とその下のノードが作る木を、そのノードの左(右)部分木と呼びます。
- 関連する用語には、根ノード、葉ノード、レベル、次数、辺、高さ、深さなどがあります。
- 初期化、ノードの挿入・削除の方法は、連結リストと似ています。
- 主な種類には、パーフェクト二分木、完全二分木、全二分木、平衡二分木があります。パーフェクト二分木は最も理想的な状態で、連結リストは退化した最悪の状態です。
- 二分木は配列でも表せます。ノードの値と空の位置をレベル順に並べ、親子のインデックスの対応でポインタを実現します。
- レベル順走査は幅優先探索の一種で、一周ずつ外へ広がるように層ごとに進み、通常はキューで実装します。
- 行きがけ順、通りがけ順、帰りがけ順は深さ優先探索で、行き止まりまで進んでから戻って続ける方法です。通常は再帰で実装します。
- 二分探索木は要素を効率よく探せるデータ構造で、探索、挿入、削除の時間計算量はすべて $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$ です。