1. [1,2,3,null,4] -> [1,2,3,4]
  2. [1] -> [1]
  3. [1,2,3] -> [1,2,3]
  4. [1,null,2,null,null,null,3] -> [1,2,3]
  5. 完全二分木 [1..7] -> [1..7]
  6. [5,3,8,1,4,null,9] -> [5,3,8,1,4,9]
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
二分木の幅優先走査 (BFS)

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

二分木の幅優先走査 (BFS)

木の探索 DFS と BFS

組織図を上から見ていくとします。まず経営層、次に部長がそろって何人、その下に課長が何人。段ごとにまとめて把握したい、という見方です。ここまでの走査では、これができません。

潜っていくと、同じ段の人がばらばらに出てくる

これまでの 3 つの走査は、分かれ道に来たら片方を最後まで降りてから戻ってきます。左の部長の下の課長も、そのまた下の主任も出し切ってから、ようやく右の部長が出てきます。同じ段にいる 2 人の間に、何十人も挟まってしまうわけです。

段ごとにまとめたいなら、潜るのを後回しにする必要があります。今の段の人を全員出し切ってから、次の段へ降りたい。再帰は「呼んだらその場で最後まで走る」ので、後回しにする置き場を自分で用意することになります。

順番待ちの列に並ばせる

やることは 1 つだけです。訪問する予定のノードを列に並べ、前から 1 つずつ呼び出します。呼び出したノードの子は、列の末尾に足します。

Python

from collections import deque def by_layer(root): names = [] waiting = deque([root]) while waiting: person = waiting.popleft() if person is None: continue names.append(person.name) waiting.append(person.left) waiting.append(person.right) return names

末尾に足して先頭から取り出すので、後から入った深い段の人が、先に並んでいた同じ段の人を追い越すことはありません。これが段ごとにそろう理由の全部です。

1 の下に 2 と 3、2 の下に 4 がある木で、列の中身を追ってみます。最初は 1 だけ。1 を呼ぶと列は 2, 3 になります。2 を呼ぶと 3, 4。3 を呼ぶと 4 だけが残り、最後に 4 が出ます。出てきた順は 1, 2, 3, 4 で、段の区切りどおりです。

取り出す側を変えると、性格が入れ替わります。

Python

waiting.popleft() # 前から取ると、段ごとにそろう waiting.pop() # 後ろから取ると、深く潜っていく

最後に入れた子がすぐ呼ばれるので、後者はそのまま 1 本の枝を降りていきます。同じ入れ物でも、どちら側から取り出すかだけで、幅を優先するか深さを優先するかが決まるわけです。

空の席まで並ばせてしまう

上のコードは、子がいるかを確かめずに列へ足しています。代わりに、取り出した直後に空かどうかを見て読み飛ばしています。入れる前に弾いても、出したあとに弾いてもかまいませんが、両方さぼると空の値が結果に混ざります。

配列で受け取っている場合は、確かめることが 1 つ増えます。子の番号が配列の外にはみ出していないか。ここを見ないと、葉のさらに先で範囲外を読みます。

もう 1 つ、Python では列に list を使わないでください。pop(0) は先頭を抜いたあとに残り全部を前へ詰め直すので、ノードが増えるほど重くなります。deque の popleft なら詰め直しは起きません。列に対して前から取り出す操作は、この走査で毎回発生します。

要件

  1. tree は BFS 順の配列で、null (Python では None) は欠損ノードを表す
  2. キュー (FIFO) を使ってレベル順に訪問する
  3. 戻り値は訪問順の値の配列。null は結果に含めない

入出力例

levelOrder([1,2,3,null,4]) → [1,2,3,4] levelOrder([1]) → [1] levelOrder([1,2,3]) → [1,2,3] levelOrder([1,null,2,null,null,null,3]) → [1,2,3] levelOrder([1,2,3,4,5,6,7]) → [1,2,3,4,5,6,7] levelOrder([5,3,8,1,4,null,9]) → [5,3,8,1,4,9]

ヒント

Python は collections.deque、JS は配列の shift/push でキューを表現できる

キューに index 0 (ルート) を入れ、while ループで取り出して値追加 + 左右の子を入れる

取り出した index が範囲外または null のときは continue で飛ばす

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 二分木の高さ

    二分木を配列表現で受け取り、根から葉までの最大のノード数 (高さ) を返す関数を実装する。

  • 二分木の平衡判定

    二分木を配列表現で受け取り、すべてのノードで左右部分木の高さの差が 1 以下なら true を返す関数を実装する。

  • 第2章まとめクイズ — 二分木

    二分木の走査 (in-order / pre-order / post-order / BFS) と高さ・平衡判定について理解度を確認する。

  • BST に値を挿入する

    二分探索木 (BST) に新しい値を挿入し、挿入後の in-order 走査結果を配列で返す関数を実装する。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 再帰関数が自分自身を呼び出す処理パターン
  • 配列サイズ固定の同型データの集まり
  • treeディレクトリ構造をツリー表示するコマンド
  • None「値がない」ことを表す特別な値。
  • キュー先入れ先出し(FIFO)のデータ構造
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

二分木の幅優先走査 (BFS)

⌘S で保存