mirror of
https://github.com/krahets/hello-algo.git
synced 2026-11-02 11:15:19 +08:00
* 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
4.3 KiB
4.3 KiB
二分木の走査
物理的な構造として、木は連結リストに基づくデータ構造なので、ポインタでノードを一つずつ訪問します。ただし、木は非線形なので、連結リストの走査より複雑で、探索アルゴリズムを使う必要があります。
主な方法には、レベル順、行きがけ順、通りがけ順、帰りがけ順などがあります。
レベル順走査
下図のレベル順走査(level-order traversal)は、上から下へ層ごとに進み、各層では左から右へノードを訪問します。
これは本質的に幅優先走査(breadth-first traversal)であり、幅優先探索(breadth-first search, BFS)とも呼びます。一周ずつ外へ広がるように、層ごとに走査する方法です。
コードの実装
幅優先走査は通常、キューで実装します。キューの「先入れ先出し」と、幅優先走査の「層ごとに進む」という規則は、同じ考え方に基づいています。実装は次のとおりです。
[file]{binary_tree_bfs}-[class]{}-[func]{level_order}
計算量の解析
- 時間計算量は $O(n)$:全ノードを一回ずつ訪問するため、
O(n)時間です。nはノード数です。 - 空間計算量は $O(n)$:最悪の場合、つまりパーフェクト二分木では、最下層の走査直前に最大
(n + 1) / 2個のノードが同時にキューに入り、O(n)の領域を使います。
行きがけ順・通りがけ順・帰りがけ順走査
これに対し、行きがけ順、通りがけ順、帰りがけ順は、いずれも深さ優先走査(depth-first traversal)です。深さ優先探索(depth-first search, DFS)とも呼び、行き止まりまで進んでから戻り、探索を続ける方法です。
下図は二分木の深さ優先走査の仕組みです。木全体の外周を一周歩くようなものです。各ノードで三つの位置を通り、それぞれが行きがけ順、通りがけ順、帰りがけ順に対応します。
コードの実装
深さ優先探索は通常、再帰で実装します。
[file]{binary_tree_dfs}-[class]{}-[func]{post_order}
!!! tip
反復でも実装できます。興味があれば調べてみてください。
下図は行きがけ順走査の再帰過程です。「呼び出し」と「戻り」という、逆方向の二つの部分に分けられます。
- 「呼び出し」では新しいメソッドの実行を始め、次のノードを訪問します。
- 「戻り」は関数から戻ることで、現在のノードの訪問が終わったことを表します。
計算量の解析
- 時間計算量は $O(n)$:全ノードを一回ずつ訪問するため、
O(n)時間です。 - 空間計算量は $O(n)$:最悪の場合、木が連結リストに退化すると再帰の深さが
nとなり、スタックフレームにO(n)の領域を使います。












