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

5.3 KiB
Raw Blame History

まとめ

要点の振り返り

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