メインコンテンツへスキップ
基本情報技術者基本情報科目B擬似言語アルゴリズム

基本情報 科目B 二分探索のトレース練習|ソート済み配列を半分ずつ絞り込む

科目Bの最頻出かつ最難関アルゴリズム「二分探索」を、lo・hi・mid の3変数を表に書いて1行ずつ追うトレースで攻略。見つかる場合と見つからない場合の両方を具体例で実演し、整数除算の切り捨てや lo←mid+1 のつまずきを解説します。

公開:

基本情報 科目B 二分探索のトレース練習

基本情報技術者試験の科目Bで、線形探索の次に必ず出会うのが 二分探索(バイナリサーチ) です。出題頻度が高い一方で、lo(下端)・hi(上端)・mid(中央)という 3 つの変数を同時に動かす ため、「今どこを見ているのか分からなくなる」と最もつまずきやすいアルゴリズムでもあります。本記事は、二分探索を変数の値を表に書きながら 1 行ずつ追う トレース で攻略する練習帳です。合計・最大値・線形探索のトレース練習 の続編として、見つかる場合・見つからない場合の両方を実演します。

本記事は 過去問AI が学習用に作成したオリジナルの例題です。掲載している擬似言語は IPA の過去問・公式サンプルの転載ではなく、説明用に書き起こしたものです。擬似言語の正式な記述形式は必ず IPA 公式ページ で確認してください。記法そのものの読み方は 基本情報 科目Bの擬似言語 記法早見表 にまとめています。

二分探索は「半分に絞り込む」検索

線形探索が先頭から 1 つずつ調べるのに対し、二分探索は 真ん中を見て、探したい値がそれより大きいか小さいかで、調べる範囲を半分に捨てていく 検索です。1 回比べるごとに候補が半分になるので、要素数が大きいほど劇的に速くなります。たとえば 1,000 個の配列でも、線形探索なら最悪 1,000 回比べるところを、二分探索は約 10 回(2 の 10 乗が 1,024)で済みます。

ただし二分探索には 絶対の前提条件 があります。

  • 配列が並べ替え済み(昇順または降順にソート済み)であること。並んでいない配列に二分探索は使えません
  • 本記事では昇順(小さい順)にソート済みの配列を前提にします

この記事の例題は、すべて次の約束ごとで進めます(科目Bの標準的なルールです)。

  • 代入は ←(右の値を左の変数に入れる)。条件式の中の = は「等しいか?」の比較
  • 配列の 要素番号は 1 から始まる。A[1] が先頭、A[要素数] が末尾
  • mid ← (lo + hi) ÷ 2 の ÷ は 商の整数部分(小数点以下は切り捨て)。例:(1 + 7) ÷ 2 = 4、(1 + 3) ÷ 2 = 2、(5 + 5) ÷ 2 = 5

記法そのものが不安なら、先に 記法早見表 で ← や ÷ の扱いを確認してから戻ってくるとスムーズです。

例題のコード

昇順にソート済みの配列 A = {2, 5, 8, 11, 14, 17, 20}(要素数 7)から、値 key を探して 何番目にあるか を返すコードです。

整数型: lo ← 1
整数型: hi ← 7
整数型: mid
整数型: 位置 ← -1
while ((lo ≦ hi) and (位置 = -1))
    mid ← (lo + hi) ÷ 2
    if (A[mid] = key)
        位置 ← mid
    elseif (A[mid] < key)
        lo ← mid + 1
    else
        hi ← mid - 1
    endif
endwhile

読み方はこうです。lo と hi で「今調べている範囲の下端と上端」を表し、その真ん中 mid を見ます。A[mid] が key と一致すれば位置を記録して終了。A[mid] が key より小さければ、答えは mid より 右 にあるので下端を lo ← mid + 1 と上げる。逆に大きければ、答えは mid より 左 なので上端を hi ← mid - 1 と下げる。これを範囲がある(lo ≦ hi)かつ未発見(位置 = -1)の間だけ繰り返します。

例1:見つかる場合(key = 14 を探す)

トレース表には、ループが 1 周するごとに lo・hi・mid・A[mid]・比較結果・更新後の (lo, hi)・位置 を書きます。

ループ回lohimidA[mid]判定更新後 (lo, hi)位置
開始前17−−−(1, 7)-1
1周目1741111 < 14 → 右へlo ← 5 で (5, 7)-1
2周目5761717 > 14 → 左へhi ← 5 で (5, 5)-1
3周目5551414 = 14 → 一致位置 ← 55

3 周目で A[5] = 14 が key と一致し、位置に 5 を記録します。次に継続条件 (lo ≦ hi) and (位置 = -1) を見ると、位置が 5(≠ -1)なので 偽 になり、ループが終わります。答えは 位置 = 5(14 は配列の 5 番目)。

注目すべきは 範囲の絞り込み方 です。1 周目で「11 より右」と分かった瞬間、左半分(A[1]〜A[4])はもう二度と見ません。これが半分ずつ捨てる動きで、線形探索なら 5 回かかる検索が 3 回で終わっています。

例2:見つからない場合(key = 10 を探す)

配列に存在しない値を探すと、二分探索がどう「無い」と判断するかが分かります。

ループ回lohimidA[mid]判定更新後 (lo, hi)位置
開始前17−−−(1, 7)-1
1周目1741111 > 10 → 左へhi ← 3 で (1, 3)-1
2周目13255 < 10 → 右へlo ← 3 で (3, 3)-1
3周目33388 < 10 → 右へlo ← 4 で (4, 3)-1
判定43−−lo > hi → 終了−-1

3 周目で lo が 4、hi が 3 になり、lo > hi(下端が上端を追い越した)状態になりました。これは「調べる範囲が無くなった」という意味で、継続条件 (lo ≦ hi) が偽になりループ終了。位置は最初の -1 のまま変わらず、「key は配列に無い」と分かります。線形探索と同じく、ありえない値 -1 を初期値にしておき、最後まで変わらなければ未発見 と判断するパターンです。

つまずきやすい3つのポイント

  1. mid は整数除算で切り捨て。(lo + hi) ÷ 2 で小数が出たら必ず切り捨てます。(1 + 2) ÷ 2 は 1.5 ではなく 1。ここを四捨五入すると以降の値が全部ずれます。
  2. lo ← mid + 1 / hi ← mid - 1 の「±1」を忘れない。mid 自身はもう調べ済みなので、次の範囲から mid を外す ために +1 / -1 します。これを lo ← mid のように書くと、範囲が縮まらず 無限ループ になる危険があります。
  3. そもそもソート済みか確認する。二分探索は並べ替え済みの配列にしか使えません。問題文で「昇順に整列されている」などの条件を必ずチェックしてください。並んでいなければ線形探索を使います。

トレースで詰まらないためのコツ

二分探索は変数が 3 つに増えるぶん、表の 列を最初に lo・hi・mid・位置 と決めてしまう のが最大のコツです。あとは 1 行進むごとに、変わった変数だけ書き換えていけば、頭で覚えなくても確実に追えます。範囲 (lo, hi) を毎回書いておくと、「今どこを見ているか」が一目で分かり、迷子になりません。

次のステップ

二分探索が追えるようになったら、出題範囲のアルゴリズムを一通りトレースで体験するのが近道です。基礎の 合計・最大値・線形探索のトレース練習 をまだ見ていなければ先にそちらを、並べ替えの定番は ソート(整列)のトレース練習 で選択ソートを二重ループのまま 1 行ずつ追えます。読む速度を上げる訓練法は 基本情報科目B|擬似言語アルゴリズム読解の3ステップ訓練法 で扱っています。つまずきが記法なのかトレースなのか切り分けたいときは 科目Bがわからない人へ、科目B 全体の進め方は 基本情報技術者 科目B完全対策 が地図になります。

手を動かす練習台としては、過去問AI の 基本情報 アルゴリズムとプログラミング分野の過去問 が使えます(こちらは科目A 相当の選択式で、科目B そのものの形式ではない点だけ意識してください)。各問題ページの AI コパイロットに「この二分探索のコードを lo・hi・mid を列にした表で 1 行ずつトレースして」と頼めば、本記事と同じ追い方を対話でその場で再現できます。

よくある質問

Q. 二分探索はソートされていない配列でも使えますか? 使えません。二分探索は「真ん中より大きいか小さいか」で範囲を半分に捨てるため、配列が昇順または降順に並んでいることが絶対の前提です。並んでいない配列では捨てた側に答えがある可能性があり、正しく動きません。並べ替えられていない場合は線形探索(先頭から順に調べる)を使います。問題文に「昇順に整列されている」などの条件があるか必ず確認してください。

Q. mid ← (lo + hi) ÷ 2 で小数が出たらどうしますか? 小数点以下を切り捨てます。擬似言語の ÷ は整数どうしなら商の整数部分を表すため、(1 + 2) ÷ 2 は 1.5 ではなく 1 です。四捨五入や切り上げをすると以降の値がすべてずれ、答えが合わなくなります。「割り切れないときは小さいほうの整数」と覚えておくと安全です。

Q. lo ← mid + 1 の「+1」を書かないとどうなりますか? 調べる範囲が縮まらず、無限ループになる危険があります。mid の位置はすでに比較済みなので、次に調べる範囲からは mid を外す必要があり、そのために下端なら +1、上端なら -1 します。lo ← mid のように書くと、同じ mid を何度も計算し続けてループが終わらなくなることがあります。

Q. 二分探索は線形探索よりどのくらい速いのですか? 1 回比べるごとに候補が半分になるため、要素数が大きいほど差が開きます。要素数 n に対し、線形探索は最悪 n 回、二分探索は約 log2(n) 回です。たとえば 1,000 個なら線形探索は最悪 1,000 回、二分探索は約 10 回(2 の 10 乗が 1,024)で済みます。ただし二分探索を使うには配列がソート済みである必要があり、その並べ替えのコストも含めて使い分けます。

まとめ

  • 二分探索は 真ん中を見て範囲を半分ずつ捨てる 検索。ソート済み配列が絶対の前提
  • 変数は lo(下端)・hi(上端)・mid(中央)・位置。表の列を先に決めて 1 行ずつ追う
  • mid ← (lo + hi) ÷ 2 は 小数点以下切り捨て。lo ← mid + 1 / hi ← mid - 1 の ±1 を忘れない
  • 見つからないときは lo > hi になって終了し、位置は -1 のまま
  • 要素数が大きいほど線形探索より圧倒的に速い(最悪 n 回 → 約 log2(n) 回)

線形探索 → 二分探索とトレースで追えるようになれば、科目Bのアルゴリズム設問は確実に読めるようになります。

基本情報技術者 の過去問で実戦演習する

記事の内容を実戦で確認しましょう。AI コパイロット付きで分からない点はその場で解決できます。

この記事に関連する過去問

関連記事

※ 本記事は 過去問AI が独自にまとめた学習ガイドです。試験要項の最新情報は必ず IPA 公式ページで確認してください。