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

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

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な 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分

二分木の post-order 走査

木を使い終わり、ノードを 1 つ残らず解放する場面を考えます。手でメモリを返す言語では、ここを間違えると二度と使えない領域が残り続けます。

親を先に消すと、子に手が届かない

根から消していくとどうなるでしょうか。根を解放した瞬間、そこに書いてあった左と右の行き先も一緒に消えます。

Python

def wrong_free(node): if node is None: return free(node) # 先に自分を消した wrong_free(node.left) # もう読めない場所を読んでいる wrong_free(node.right)

運が良ければその場で落ちます。悪ければ、すでに他の用途へ配られた領域を読み、まったく無関係な値をノードとして扱い始めます。落ちる場所と原因が離れるので、追いかけるのがとても難しいバグになります。

子を片付けてから、自分を片付ける

順序を入れ替えるだけで解決します。

Python

def free_tree(node): if node is None: return free_tree(node.left) free_tree(node.right) free(node) # 自分は最後

左、右、自分。これが post-order です。自分を消す時点で、下にぶら下がっていたものはすべて片付いています。裏を返せば、自分を触るまでは子の情報が生きている、ということでもあります。

根が 1、左が 2、右が 3 の木で追ってみます。左へ降りて 2 を片付け、右へ降りて 3 を片付け、戻ってきて 1 を片付ける。並べると 2, 3, 1 です。根が最後にいるのが post-order の顔です。

下から答えを持ち上げる形は、全部これになる

解放だけの話ではありません。子の計算結果を受け取ってから自分の値を決める処理は、必ずこの順になります。フォルダの合計容量、部下の総数、閉じタグを書き出す順番。どれも下が確定するまで上が決まりません。

たとえばタグを組み立てる処理も同じ形です。

Python

def to_html(node): if node is None: return "" inner = to_html(node.left) + to_html(node.right) return "<" + node.tag + ">" + inner + "</" + node.tag + ">"

中身が全部できあがるまで、閉じタグは書けません。だから子を先に組み立て、そのあとで自分の開きと閉じで挟みます。

逆に、自分の値が先に決まるなら post-order である必要はありません。単に値を並べるだけなら、どの順でも全ノードを 1 回ずつ訪れます。順序を選ぶ基準は「上が下の答えを必要とするかどうか」です。ここが分かると、木の問題でどの順を選ぶかで迷わなくなります。

書くときに間違えやすいのは、右の再帰の書き忘れです。左だけ書いても動いてしまい、左端の枝だけをたどって終わります。結果の件数がノードの数と合わないときは、まずここを疑ってください。もう 1 つは行き止まりの判定です。配列で受け取っている以上、範囲の外に出ていないかと、その場所が空でないかの両方を確かめる必要があります。片方だけだと、深い木で必ず落ちます。

なお、走査した結果を並べたとき、末尾に根が来ていれば post-order です。手元の出力がどれなのか分からなくなったら、最後の 1 件を見てください。

要件

  1. tree は BFS 順の配列で、null (Python では None) は欠損ノードを表す
  2. 再帰または反復で left -> right -> root の順に訪問する
  3. 戻り値は訪問順の値の配列。null は結果に含めない

入出力例

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

ヒント

index i の左の子は 2*i+1、右の子は 2*i+2

in-order や pre-order と違うのは result.append(tree[i]) を最後に置くこと

「子を全部処理してから親を処理する」と考えると post-order が腑に落ちる

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

関連レッスン

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

    二分木を配列表現で受け取り、レベル順 (BFS) で訪問した値の配列を返す関数を実装する。

  • 二分木の高さ

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

  • 二分木の平衡判定

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

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

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

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

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

  • メモリプログラムとデータを一時保持する高速領域
  • 処理計算や代入を表す長方形
  • 再帰関数が自分自身を呼び出す処理パターン
  • 配列サイズ固定の同型データの集まり
  • treeディレクトリ構造をツリー表示するコマンド
  • None「値がない」ことを表す特別な値。
  • 反復色やフォントを繰り返して秩序を生む
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

二分木の post-order 走査

⌘S で保存