木の巡回|先行順・中間順・後行順のちがい【基本情報技術者試験 科目B】

基本情報技術者試験

現行FE シラバス Ver9.2 準拠擬似言語の記述形式は2022年から変更なし最終更新 2026-10-11

木の巡回とは、木の節を、決まった順番で1つ残らず1回ずつ訪ねることです。順番の決め方には先行順・中間順・後行順の3つがあり、プログラムの上でのちがいは、たった1行の位置だけです。サンプル問題には、巡回のプログラムが節番号をどの順に出力するかを答える出題があります。5つの節の小さな木で確かめます。

期間限定クーポンPR|Udemy の講座科目B オリジナル模試 3回分・60問42%OFF 1,500円2,600円中身を見る ›

木の巡回とは ── すべての節を、1回ずつ訪ねる

下の図が、この回で使う木です。箱の1つ1つを節(せつ)といい、1 から 5 の節番号を付けてあります。線で下につながった節が子で、子は左の子と右の子を区別します。いちばん上の節1 が根、子のない節3・節4・節5 が葉です。このように、どの節も子が2つ以下の木を2分木といいます。

この回で巡回する木(節は5つ)

色の付いた箱=子が2つある節 / 点線の箱=子のない節(葉)。線の上側が親、下側が子(矢じりは親の側に付けてあります)

箱の太字が、配列 tree のその番号に入っているもの

節1tree[1]{2, 3}左の子は 2
右の子は 3

節2tree[2]{4, 5}左の子は 4
右の子は 5

節4tree[4]{}子はいない

節5tree[5]{}子はいない

節3tree[3]{}子はいない

プログラムの中では、この木を配列 tree で持ちます。tree[n] は、節 n の子の節番号を、左の子・右の子の順に並べた配列です。子のない節は {}(要素数0の配列)になります。先頭の 大域: は、どの手続からもこの配列を使える、という印です。

大域: 整数型配列の配列: tree ← {{2, 3}, {4, 5}, {}, {}, {}}

もう1つ、言葉を用意します。ある節と、その下につながる節をまとめたものを、その節を根とする部分木といいます。節2 を根とする部分木は、節2・節4・節5 の3つです。節1 から見ると、これが左の部分木、節3 だけの部分木が右の部分木です。

巡回のプログラム ── 手続 order が、自分を呼ぶ

次の手続 order は、引数 n で受け取った節を根とする部分木をたどって、その節番号をすべて出力します。節を訪ねるたびにその節番号を1回出力するので、出力された順が、巡回の順です。

大域: 整数型配列の配列: tree ← {{2, 3}, {4, 5}, {}, {}, {}}

○order(整数型: n)
  if (tree[n]の要素数 が 2 と等しい)
    order(tree[n][1])
    nを出力
    order(tree[n][2])
  else
    nを出力
  endif

当サイトで作った例です。

order(1) を呼び出すと、4,2,5,1,3 の順に出力されます。

order の中で、order を呼んでいます。手続が自分自身を呼ぶこの書き方を再帰といいます(A8-1 再帰とは)。読み方は、ほかの手続を呼ぶときと変わりません。

上から読む

  1.   if (tree[n]の要素数 が 2 と等しい)
    子が2つあるか。tree[n]の要素数 は、節 n の子の数です。
  2.     order(tree[n][1])
        nを出力
        order(tree[n][2])
    左をたどる → 自分を出力 → 右をたどる。tree[n][1] は左の子、tree[n][2] は右の子の節番号です。左の子を引数にして order を呼ぶと、左の部分木がまるごとたどられます。
  3.   else
        nを出力
    子がなければ、自分を出力するだけ。ここでは order を呼びません。葉に着いたら、それより下へは降りないということです。この木には子が1つだけの節がないので、「子が2つでない」は「子がない」と同じです。

order を呼んだ側は、その行で止まって待ちます。呼ばれた側が最後の行まで終わると、呼んだ側は次の行へ進みます。だから order(1) は、左の子で order(2) を呼んだ行で待ち続け、左の部分木の 4,2,5 が全部出てから、その次の行で自分の 1 を出力します。

n は、呼び出しごとに別のものです。order(2) の中の n が 2 でも、待っている order(1) の n は 1 のまま残っています。

order(1) を1行ずつ動かす

当サイトオリジナルの例題


ループ開始前

大域の配列 tree(n 番目が、節 n の子の番号)

▲ いま読んでいる▲ いま書いた

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると1行ずつ積み上がります)

先行順・中間順・後行順 ── 「nを出力」の位置で決まる

if の中の3行は、「左の子で order を呼ぶ」「nを出力」「右の子で order を呼ぶ」の3つでした。nを出力 を、2つの呼び出しの前に置くと先行順、あいだに置くと中間順、後ろに置くと後行順です。左を右より先に呼ぶところと、else の側は、3つとも変わりません。

同じ木を、3つの順で出力する

各段の上=if の中の3行 / 下=order(1) の出力。枡の上の数字=何番目に出力されるか / 色の枠=根の節1 / すき間=3つのかたまり(根・左の部分木・右の部分木。並ぶ順は段ごとにちがう)の切れ目

先行順 ── 自分を出力 → 左 → 右

nを出力
order(tree[n][1])
order(tree[n][2])

11

 

22

34

45

 

53

出力は 1,2,4,5,3。根の 1 が最初に出ます。左の部分木(節2・4・5)の中も同じ並べ方で、自分の 2 が先、続いて 4、5。

中間順 ── 左 → 自分を出力 → 右

order(tree[n][1])
nを出力
order(tree[n][2])

14

22

35

 

41

 

53

出力は 4,2,5,1,3。根の 1 は、左の部分木が全部出たあとです。左の部分木の中も同じ並べ方で、4、自分の 2、5。上で動かしたプログラムがこれです。

後行順 ── 左 → 右 → 自分を出力

order(tree[n][1])
order(tree[n][2])
nを出力

14

25

32

 

43

 

51

出力は 4,5,2,3,1。根の 1 が最後に出ます。左の部分木の中も同じ並べ方で、4、5、最後に自分の 2。

3つとも、左の部分木・根・右の部分木という3つのかたまりを、3行の並びと同じ順に置いたものになっています。かたまりの中の並びも、同じ決まりです。だから、プログラムを1行ずつ追わなくても、木の図からこの並びを書き出せます。

木の図から、手で順番を書き出す

  1. プログラムの3行の並びを見る。nを出力 が、2つの呼び出しの前・あいだ・後ろのどこにあるかを確かめます。
  2. 根のところで、木を3つに分ける。左の部分木・根・右の部分木です。部分木は、まだ中を見ずに、ひとかたまりのまま置きます。
  3. 3つを、プログラムの並びどおりに並べる。前なら「根 → 左の部分木 → 右の部分木」、あいだなら「左の部分木 → 根 → 右の部分木」、後ろなら「左の部分木 → 右の部分木 → 根」です。
  4. かたまりの中も、同じ並べ方で開く。左の部分木なら、その根(上の木では節2)で、また3つに分けます。節が1つだけになったら、その節番号を書きます。
本物もこう書かれる

(基本情報技術者試験 科目B サンプル問題 問9)

手続order は,図の2 分木の,引数で指定した節を根とする部分木をたどりながら,全ての節番号を出力する。

14個の節をもつ木を order(1) でたどり、出力の順を解答群から選ぶ出題です。nを出力 は2つの呼び出しのあいだにあります。問題文に「中間順」という語は出てこないので、順番は3行の並びから読み取ります。子が1つだけの節があるため、「子が1つなら、左の子をたどってから自分を出力する」という場合分けが1つ多くなっています(サンプル問題 問9の解説)。

次に読む

A13 グラフ ─ 隣接行列の読み方と、深さ優先探索・幅優先探索
問9 サンプル問題 問9の解説 ─ 14個の節の木を order でたどる
A11 木構造 ─ 根・葉・親子と、2分木を配列で表す方法
A8-2 再帰のトレース ─ 呼び出しを下へ書き、下から埋める
目次 基本情報技術者試験 科目B 攻略ガイド

この記事で引用した資料

いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では、引用した箇所の文言を改変していません(省略や補いがある場合は、その場に明記しています)。

本文の例題(5つの節の木と手続 order)は当サイトのオリジナルです。

タイトルとURLをコピーしました