2分探索|まん中と比べて、探す範囲を半分にする【基本情報技術者試験 科目B】

基本情報技術者試験

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

2分探索は、小さい順に並んだ配列から目当ての値を探すやり方です。まん中の1つと比べるたびに、探す範囲が半分になります。

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

2分探索とは ── まん中と比べて、半分を捨てる

6個の値が小さい順に並んだ配列から、47 が何番目にあるかを探します。見るのは毎回、探す範囲のまん中の1つだけです。

47 を探す ── 1回比べるたびに、探す範囲が半分になる

整数型の配列: data ← {11, 23, 35, 47, 59, 62} / ▲=いま比べている、まん中の枡 / 下の3つの箱=探す範囲の左端・右端と、まん中が何番か / 灰色の枡=47 は無いと分かって、もう見ない枡 / 緑の枡=探している値と同じだった枡

1回目 探す範囲は 1〜6番

data

111

223

335▲

447

559

662

左端1

右端6

まん中3

まん中は (1 + 6) ÷ 2 = 3.5、小数を切り捨てて 3番。3番の 35 は 47 より小さい。小さい順に並んでいるので、3番から左はどれも 35 以下 ── 47 は 1〜3番には無い。左端を 4 にする。

2回目 探す範囲は 4〜6番

data

111

223

335

447

559▲

662

左端4

右端6

まん中5

まん中は (4 + 6) ÷ 2 = 5 で 5番。5番の 59 は 47 より大きい。5番から右はどれも 59 以上 ── 47 は 5〜6番には無い。右端を 4 にする。

3回目 探す範囲は 4番だけ

data

111

223

335

447▲

559

662

左端4

右端4

まん中4

まん中は (4 + 4) ÷ 2 = 4 で 4番。4番の 47 は、探している 47 と同じ。見つかった ── 答えは 4(番目)。

6個の中から、まん中を3回見ただけで見つかった。

毎回やることは同じです。

まん中の値が、探している値より…

小さい ── まん中から左には無い。左端を、まん中の1つ右へ動かす

大きい ── まん中から右には無い。右端を、まん中の1つ左へ動かす

同じ ── 見つかった。まん中の番号が答え

1回比べるたびに範囲が半分になるので、配列が大きくても比べる回数は少なくて済みます。1000個あっても、1000 → 500 → 250 → … と半分にするのを10回ほどくり返せば、残りは1個です。前から1つずつ比べていく線形探索だと、目当ての値が最後にあれば1000回かかります。

並んでいることが前提

まん中の1つを見ただけで半分を捨てられるのは、配列が小さい順に並んでいるからです。並んでいない配列で同じことをすると、こうなります。

並んでいない配列で同じことをすると、捨てた半分に 47 が残る

整数型の配列: data ← {62, 47, 35, 11, 59, 23}(小さい順に並んでいない) / ▲=まん中の枡 / 灰色の枡=捨てた枡 / 枠に色の付いた枡=47 がある枡

1回目 まん中は 3番の 35。47 より小さいので、1〜3番を捨てる

162

247

335▲

411

559

623

ところが 47 は、捨てた 2番にあった

162

247

335

411

559

623

このあと 4〜6番をいくら探しても 47 は出てこない。配列の中にあるのに「無い」と答えてしまう。

小さい順に並んでいることを昇順といいます。この探し方を使うプログラムは、配列が昇順に並んでいることを前提にしています。

実際の出題の書き方

基本情報技術者試験 科目B サンプル問題 問13 の関数 search は、この探し方で配列 data から値を探します。問題文には「data は昇順に整列されており,値に重複はない。」と書かれています。「昇順に整列されており」は、小さい順に並べてあるという意味です。「重複はない」は、同じ値が2つ入っていないという意味です。だから、答えの要素番号は1つに決まります。なお、出題の search には不具合が1つ入れてあり、それを見つける問題になっています。

プログラムを、上から読む

ここまでの手順を関数にしたものです。配列 data と探す値 target を受け取り、見つかればその要素番号(何番目か)を、見つからなければ -1 を返します。47 を探した図の「左端」「右端」「まん中」が、変数 low・high・middle です。

○整数型: nibunTansaku(整数型の配列: data, 整数型: target)
  整数型: low, high, middle
  low ← 1
  high ← dataの要素数
  while (low ≦ high)
    middle ← (low + high) ÷ 2 の商
    if (data[middle] < target)
      low ← middle + 1
    elseif (data[middle] > target)
      high ← middle - 1
    else
      return middle
    endif
  endwhile
  return -1

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

data が {11, 23, 35, 47, 59, 62}、target が 47 なら、47 を探した図のとおり、まん中を3回見て 4 を返します。

上から読む

  1. ○整数型: nibunTansaku(整数型の配列: data, 整数型: target)
    関数の宣言。整数型の配列と整数を1つずつ受け取り、整数型の値を返す関数です。要素番号は 1 から数えます(サンプル問題 問13 の問題文にも「配列の要素番号は1 から始まる。」とあります)。
  2.   整数型: low, high, middle
      low ← 1
      high ← dataの要素数
    探す範囲の両端。low が左端、high が右端の要素番号です。はじめは配列の全体なので、1 と、data に入っている値の個数(dataの要素数)を入れます。
  3.   while (low ≦ high)
    範囲に1つでも残っているあいだ、くり返す。while は、かっこの中が成り立つあいだ endwhile までをくり返します。≦ は「以下」です。low と high が同じなら、残りは1個です。
  4.     middle ← (low + high) ÷ 2 の商
    まん中の番号を決める。÷ 2 の商 は、2で割った答えの整数の部分です。(1 + 6) ÷ 2 は 3.5 なので、商は 3 になります。
  5.     if (data[middle] < target)
          low ← middle + 1
        elseif (data[middle] > target)
          high ← middle - 1
    半分を捨てる。data[middle] は、data の middle 番目の値 ── まん中の値です。if から endif までは、上から if、elseif の順に条件を見て、最初に成り立った1か所だけを実行します。まん中の値のほうが小さければ左端を、大きければ右端を動かします。middle 番はいま見て「ちがう」と分かったので、+ 1・- 1 をして範囲から外します。
  6.     else
          return middle
        endif
    見つかった。else は、上のどの条件も成り立たなかったときに実行されます。小さくも大きくもないなら、同じ値です。return middle は middle の値(まん中の番号)を返して、くり返しの途中でも関数を終わります。
  7.   endwhile
      return -1
    最後まで無かったとき。while を抜けると return -1 の行に来ます。要素番号は 1 からなので、-1 は番号としてありえない値 ── 呼んだ側は「無かった」と判断できます。

終わり方は2つ ── 見つかったとき、範囲が空になったとき

この関数が終わる場所

見つかった ── まん中の値が target と同じだった。return middle で終わる

範囲が空 ── low ≦ high が成り立たなくなって while を抜けた。return -1 で終わる

1つ目は、47 を探した図の3回目です。middle が 4 で、data[4] が 47 と同じなので、return middle で 4 を返します。2つ目を、同じ配列で入っていない値 20 を探して確かめます。

入っていない値 20 を探す

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


ループ開始前

配列

▲ いま読んでいる

いま計算していること

まだ計算していません

変数の状態

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

左端が右端より右に来たら、範囲には1つも残っていません。だから while を抜けて、-1 を返します。

くり返しのたびに、middle 番は必ず範囲から外れます。範囲は毎回1つ以上せまくなるので、見つからない場合もいつかは空になり、くり返しは終わります。

次に読む

A7-2 ハッシュ表探索 ─ 入れる場所を計算で決める
A2-3 線形探索 ─ 前から1つずつ照らし合わせる
問13 サンプル問題 問13の解説 ─ この探し方の関数 search から不具合を見つける問題
目次 基本情報技術者試験 科目B 攻略ガイド

この記事で引用した資料

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

本文の例題とプログラムは当サイトのオリジナルです。

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