資格道場 › レッスン一覧 › アルゴリズムとプログラミング
アルゴリズムとプログラミング・9/13・13分

探索アルゴリズムと計算量

ゴール

線形探索・2分探索・ハッシュ探索の違い(前提条件と計算量)を説明でき、2分探索の流れ図の空欄補充と、計算量の比例計算・平均比較回数の計算を自力で解けるようになる。

「データの山から目的の1件をどう速く探すか」は、DB のインデックスや API の検索処理の土台になる考え方です。試験では「2分探索は整列済みが前提」「2分探索の計算量は log₂n」の2点が、本試験・免除試験の両方で繰り返し出ています。

このレッスンで稽古する(用語チェック・過去問)

まず全体像:探索の3兄弟

探索の方法は、試験ではほぼ線形探索・2分探索・ハッシュ探索の3つに絞られます。違いは「データがどう並んでいる必要があるか(前提)」と「データ量 n が増えたとき、手間がどう増えるか(計算量)」の2点です。まずこの表を丸ごと覚えてください。

線形探索 2分探索 ハッシュ探索
やり方 先頭から1件ずつ比べる 真ん中と比べ、範囲を半分に絞る キーから計算した位置(ハッシュ値)を直接見る
データの前提 なし(バラバラでよい) キーで整列済み(昇順など) ハッシュ関数で決まる位置に格納済み
計算量(オーダ) n log₂n 1(衝突を無視した場合)
n=1,024 件のときの比較回数の目安 最大 1,024 回 約 10 回 約 1 回

計算量とは「データ数 n に対して処理の手間がどう増えるか」を表すもので、オーダはその増え方の大まかな形(n に比例、log₂n に比例など)を指します。定数倍は無視して、形だけで比べます。

線形探索:流れ図は「どこで止まるか」を読む

線形探索は、配列の先頭(k=1)から順に「目的の値 X と等しいか」を比べ、等しければそこで終了します。見つからなければ k を 1 増やし、k が N を超えたら終了します。

流れ図の問題では、終了したときの k の値だけを押さえれば解けます。

状況 終了時の k
X が配列にない N+1(N を超えた時点でループを抜けるため)
X が1か所だけにある その位置
X が複数か所にある 最初に一致した位置(そこで止まるので後ろは見ない)

比較回数を減らすコツ:線形探索は前から調べるので、よく出るものを前に置くほど平均の比較回数が減ります。処理区分の判定なら、出現比率が大きい区分から先に判定するのが正解です。

Xが2か所(3番目と5番目)にあるABXCXDk=1k=2k=3k=4k=5k=6比較比較一致見ない見ない見ないk=3 で終了(最初に一致した位置)Xが配列にない(N=6)ABCDEF範囲外k=1k=2k=3k=4k=5k=6k=7k=7(N+1)で終了:Nを超えたから
線形探索は前から順に比べ、最初に一致した所で止まる。見つからなければ k は N+1 で終わる。

2分探索:前提は「整列済み」、中央は (x+y)/2

2分探索は、辞書で単語を引くときに真ん中あたりを開き、「目的の語はこのページより前か後か」で半分を捨てる動きと同じです。辞書が五十音順に並んでいるから前後を判断できるのであって、バラバラに並んだデータには使えません。これが最頻出の「前提条件」の論点です。

流れ図の決まり文句(探索範囲の下端を x(lo)、上端を y(hi)とする):

  • 中央の添字(配列の何番目かを表す番号):(x+y)/2(小数点以下切捨て)
  • 中央の値 < 探す値 → 目的は右半分 → 下端を m+1 にする
  • 中央の値 > 探す値 → 目的は左半分 → 上端を m−1 にする
  • 下端 > 上端 になったら範囲が空 → 見つからない

±1 するのは、今調べた m 自体はもう候補ではないからです。

flowchart TD
  A["x←1, y←n"] --> B{"x ≦ y ?"}
  B -- "No" --> Z["見つからない"]
  B -- "Yes" --> C["m←(x+y)/2"]
  C --> D{"A(m) と k を比較"}
  D -- "等しい" --> E["見つかった"]
  D -- "k が小さい" --> F["y←m−1(左半分へ)"]
  D -- "k が大きい" --> G["x←m+1(右半分へ)"]
  F --> B
  G --> B

探索表の並び方で手法を選ぶ問題も同じ考え方です。コード順に並んだ表 → 2分探索、使用頻度順に並んだ表(整列していない)→ 線形探索、コードから一意に場所が決まる表 → ハッシュ表探索、と対応させます。

例:整列済みの配列から 21 を探す1234567381217212630x=1, y=7, m=4:17<21 → x←m+1=5381217212630x=5, y=7, m=6:26>21 → y←m−1=5381217212630x=5, y=5, m=5:21=21 → 見つかった
整列済みの配列で21を探す例。中央 m と比べるたびに x か y が m±1 に動き、範囲が半分になる。

計算量:log₂n を体で覚える

2分探索は1回比べるごとに候補が半分になります。n 件が 1 件になるまでに半分にする回数は、2 を何乗すると n になるか、つまり log₂n 回です。1,024 件なら 2¹⁰=1,024 なので約 10 回、約100万件でも約 20 回で済みます。

オーダ 代表例 n=1,000 のときの目安
1 ハッシュ探索 1
log₂n 2分探索 約 10
n 線形探索 1,000
n log₂n 速い整列(クイックソートの平均など) 約 10,000
n² 単純な整列(バブルソートなど) 1,000,000
n³ 連立一次方程式の解法など 1,000,000,000

注意点として、2分探索は「1件を探す」処理なので log₂n、n log₂n は「全件を整列する」処理のオーダです。選択肢で並ぶので取り違えないでください。また、2分探索が線形探索より「常に」速いわけではありません(目的が先頭にあれば線形探索は1回で終わります)。

候補が半分ずつ減っていく様子1,024件512件1回256件2回128件3回64件4回32件5回16件6回8件7回4件8回2件9回1件10回2¹⁰=1,024 なので約10回(log₂n)
1回比べるごとに候補が半分になり、1,024件は10回で1件まで絞れる(2¹⁰=1,024)。

ブロック分割探索:2段階の線形探索

整列済みの n 件を m 件ずつのブロックに分け、まず各ブロックの最後尾だけを線形探索して「どのブロックにあるか」を決め、次にそのブロック内を線形探索します。線形探索の平均比較回数は「候補数の約半分」なので、ブロック選び (n/m)/2 回+ブロック内 m/2 回で、平均 m/2 + n/(2m) になります。

例:n=12, m=4 で 18 を探すブロック1ブロック2ブロック325791215182023262931段階1:各ブロックの最後尾だけ比べる9<1820≧18見ない→ ブロック2に決定段階2:ブロック2の中を前から比べる12151820比較比較一致見ない平均 m/2 + n/(2m) 回この例なら 4/2 + 12/8 = 3.5 回
まず各ブロックの最後尾だけを比べてブロックを決め、次にそのブロックの中を前から比べる2段階の線形探索。

比例計算:「何乗に比例」をそのまま使う

「計算時間が n³ に比例する」と言われたら、n が 10 倍になると時間は 10³=1,000 倍です。そのうえで、演算速度が 4 倍のコンピュータなら時間は 1/4 になります。データ量の倍率を指数どおりに乗じる → 速度の倍率で割る、の2段階で解きます。

例題 1

線形探索の流れ図:終了時の k を小さな配列でなぞる

配列 A の 1 番目から N 番目の要素に整数が格納されている(N>1)。次の図は,X と同じ値が何番目の要素に格納されているかを調べる流れ図である。この流れ図の実行結果として,適切な記述はどれか。
流れ図: 開始 → k ← 1 → 判定「k : N」。k : N が「>」なら終了へ。「≦」なら判定「X : A(k)」へ。X : A(k) が「=」なら終了へ。「≠」なら k ← (k + 1) を実行して,再び判定「k : N」の直前へ戻る(ループ)。終了。

ア X と同じ値が配列中にない場合,k には 1 が設定されている。
イ X と同じ値が配列中にない場合,k には N が設定されている。
ウ X と同じ値が配列の 1 番目と N 番目の 2 か所にある場合,k には 1 が設定されている。
エ X と同じ値が配列の 1 番目と N 番目の 2 か所にある場合,k には N が設定されている。

出典:基本情報技術者試験 科目A免除 修了試験 20221211 実施分 問9

解き方と答えを見る
  1. N=3 の小さな例を作る。複数一致のケース:A=(5, 7, 5)、X=5 とする(1番目と N=3 番目が一致)。
  2. k←1。判定 k:N は 1≦3 なので X:A(1) へ。A(1)=5=X なので「=」で終了。終了時 k=1。
  3. → 2か所にあっても最初の位置 1 で止まるので、ウ「k には 1 が設定されている」が正しい。エ(k=N)は誤り。
  4. 念のため不一致のケース:A=(1, 2, 3)、X=9。k=1,2,3 と進んでどれも「≠」なので k←4。
  5. 判定 k:N は 4>3 で終了。終了時 k=4=N+1。よってア(k=1)もイ(k=N)も誤り。

答え:ウ(複数一致なら最初の位置、見つからなければ k=N+1)

例題 2

出現比率の大きい順に判定すると比較回数が減る理由

売上ファイルのレコードの項目の一つに処理区分があり,この処理区分に応じた処理をしたい。全売上データに対する各処理区分の出現比率はあらかじめ分かっている。処理区分を判定するための比較回数に関する記述のうち,適切なものはどれか。

ア 出現比率が中間の処理区分のものを先に判定すると,全体の比較回数が少なくなる。
イ 出現比率が最も大きい処理区分から先に判定すると,全体の比較回数が少なくなる。
ウ 出現比率が最も小さい処理区分から先に判定すると,全体の比較回数が少なくなる。
エ どのような順番でも全体の比較回数は同じである。

出典:基本情報技術者試験 科目A免除 修了試験 20221211 実施分 問47

解き方と答えを見る
  1. 例として処理区分 A・B・C の出現比率を 60%・30%・10% とする。
  2. 大きい順(A→B→C)に判定:A は1回、B は2回、C は3回の比較で確定する。
  3. 平均比較回数 = 0.6×1 + 0.3×2 + 0.1×3 = 0.6 + 0.6 + 0.3 = 1.5 回。
  4. 小さい順(C→B→A)に判定:平均 = 0.1×1 + 0.3×2 + 0.6×3 = 0.1 + 0.6 + 1.8 = 2.5 回。
  5. 1.5 回 < 2.5 回なので、出現比率が大きいものから判定すると全体の比較回数が少なくなる。

答え:イ

例題 3

2分探索の流れ図:lo と hi の更新を実際の値で確かめる

昇順に整列された n 個のデータが格納されている配列 A がある。流れ図は,2 分探索法を用いて配列 A からデータ x を探し出す処理を表している。a, b に入る操作の適切な組合せはどれか。ここで,除算の結果は小数点以下が切り捨てられる。
流れ図: 開始 → [1→lo, n→hi] → (ループ先頭) [(lo+hi)/2→k] → 判定 A(k):x。A(k)=x のとき「x は存在する」へ。A(k)<x のとき[a]へ。A(k)>x のとき[b]へ。[a]と[b]の後は合流して判定 lo:hi。lo≦hi のときループ先頭((lo+hi)/2→k の手前)へ戻る。lo>hi のとき「x は存在しない」へ。「x は存在する」「x は存在しない」はいずれも 終了 へ。

ア a: k+1→hi,b: k−1→lo
イ a: k−1→hi,b: k+1→lo
ウ a: k+1→lo,b: k−1→hi
エ a: k−1→lo,b: k+1→hi

出典:基本情報技術者試験 科目A免除 修了試験 20131215 実施分 問6

解き方と答えを見る
  1. n=7、A=(2, 4, 6, 8, 10, 12, 14)、探す値 x=12 とする。
  2. lo←1、hi←7。k←(1+7)/2=4。A(4)=8。
  3. A(k)=8 < x=12 なので、目的は右半分(5〜7番目)。下端を k+1 に動かす:lo←4+1=5。これが a の操作「k+1→lo」。
  4. lo=5 ≦ hi=7 なのでループ先頭へ。k←(5+7)/2=6。A(6)=12=x なので「x は存在する」で終了。
  5. 逆に A(k)>x なら目的は左半分なので上端を k−1 に動かす:「k−1→hi」が b。
  6. a=k+1→lo、b=k−1→hi の組合せはウ。

答え:ウ

例題 4

2分探索の流れ図:a に入る中央の添字

昇順に整列済みの配列要素 A(1),A(2),…,A(n) から,A(m)=k となる配列要素 A(m) の添字 m を 2 分探索法によって見つける処理を図に示す。終了時点で m=0 である場合は,A(m)=k となる要素は存在しない。図中の a に入る式はどれか。ここで,“/” は,小数点以下を切り捨てる除算を表す。
フローチャート: 開始 → [1 → x / n → y] → 判定 x:y。 - x:y が「>」→ [0 → m] → 終了 - x:y が「≦」→ [a] → 判定 k:A(m) - k:A(m) が「=」→ 終了 - k:A(m) が「<」→ [m−1 → y] → 判定 x:y に戻る - k:A(m) が「>」→ [m+1 → x] → 判定 x:y に戻る

ア (x+y) → m
イ (x+y)/2 → m
ウ (x−y)/2 → m
エ (y−x)/2 → m

出典:平成24年度 秋期 基本情報技術者試験 午前 問6

解き方と答えを見る
  1. 探索範囲は x 番目から y 番目。その真ん中の添字を求めたい。
  2. 例:x=1、y=10 なら真ん中は (1+10)/2=5.5 → 切捨てで 5。範囲 1〜10 の中にある。
  3. ア (x+y)=11 は範囲外(10 を超える)なので誤り。
  4. ウ (x−y)/2=(1−10)/2 は負の数で誤り。エ (y−x)/2=(10−1)/2=4(切捨て)は、x が 1 以外のとき範囲外になる。例:x=6、y=10 なら (10−6)/2=2 で範囲 6〜10 に入らない。
  5. 常に範囲の中央を指すのは (x+y)/2。

答え:イ

例題 5

ブロック分割探索の平均比較回数

異なる n 個のデータが昇順に整列された表がある。この表を m 個のデータごとのブロックに分割し,各ブロックの最後尾のデータだけを線形探索することによって,目的のデータの存在するブロックを探し出す。次に,当該ブロック内を線形探索して目的のデータを探し出す。このときの平均比較回数を表す式はどれか。ここで,m は十分に大きく,n は m の倍数とし,目的のデータは必ず表の中に存在するものとする。

ア m+n/m
イ m/2+n/(2m)
ウ n/m
エ n/(2m)

出典:基本情報技術者試験 科目A免除 修了試験 20230122 実施分 問9

解き方と答えを見る
  1. ブロック数は n/m 個。
  2. 段階1:各ブロックの最後尾を先頭から線形探索。目的のブロックは平均して真ん中あたりで見つかるので、平均比較回数は (n/m)/2 = n/(2m)。
  3. 段階2:ブロック内の m 件を線形探索。平均比較回数は m/2。
  4. 合計 = m/2 + n/(2m)。
  5. 数値で確認:n=10,000、m=100 なら 100/2 + 10,000/(2×100) = 50 + 50 = 100 回。
  6. ア m+n/m は最悪の場合(どちらも最後まで調べる)の回数なので、平均ではない。

答え:イ(m/2 + n/(2m))

例題 6

n³ に比例する計算時間の比例計算

コンピュータで連立一次方程式の解を求めるのに,式に含まれる未知数の個数の 3 乗に比例する計算時間が掛かるとする。あるコンピュータで 100 元連立一次方程式の解を求めるのに 2 秒掛かったとすると,その 4 倍の演算速度をもつコンピュータで 1,000 元連立一次方程式の解を求めるときの計算時間は何秒か。

ア 5
イ 50
ウ 500
エ 5,000

出典:平成23年度 秋期 基本情報技術者試験 午前 問3

解き方と答えを見る
  1. 元のコンピュータ:100 元で 2 秒。
  2. 元数の倍率:1,000 ÷ 100 = 10 倍。
  3. 計算時間は 3 乗に比例:10³ = 1,000 倍。同じコンピュータなら 2 × 1,000 = 2,000 秒。
  4. 演算速度が 4 倍なので時間は 1/4:2,000 ÷ 4 = 500 秒。
  5. ひっかけ:比例(10 倍)で計算すると 2×10÷4=5 秒(ア)、2 乗(100 倍)だと 2×100÷4=50 秒(イ)、速度で割らずに掛けると誤った値になる。

答え:ウ(500 秒)

要点(試験直前に読む)

  • 2分探索は「キーで整列済み」が前提。ランダム配置・ハッシュ配置・頻度順の表には使えない。
  • オーダ:ハッシュ探索 1、2分探索 log₂n、線形探索 n。n log₂n は整列のオーダ。
  • 2分探索の流れ図:中央は (x+y)/2(切捨て)、中央<探す値なら x←m+1、中央>探す値なら y←m−1。
  • 線形探索の流れ図:見つからなければ k=N+1、複数一致なら最初の位置で止まる。判定は出現比率の大きい順が最も速い。
  • ブロック分割探索の平均比較回数は m/2 + n/(2m)。
  • 「n³ に比例」の比例計算:(n の倍率)³ を掛けて、演算速度の倍率で割る。

ひっかけ

  • 2分探索の計算量に n log₂n が並ぶ → 1件を探すのは log₂n。n log₂n は整列のオーダと覚えて切る。
  • 「2分探索は線形探索より常に速い」 → 「常に」は誤り。目的が先頭にあれば線形探索は1回で終わる。
  • 流れ図の空欄に (x−y)/2 や (y−x)/2 → 差の半分は範囲の「幅の半分」で、位置ではない。下端と上端を足して2で割るのが中央。
  • 線形探索で「見つからないと k=N」「複数一致なら最後の位置」 → ループは N を超えてから抜けるので N+1、一致した瞬間に止まるので最初の位置。
  • ブロック分割探索や n³ の比例計算で最悪値・1乗・2乗の値が並ぶ → 「平均」か「最大」か、何乗に比例するかを問題文で確認してから計算する。

用語(13)

線形探索 せんけいたんさく
配列の先頭から1件ずつ順に比べて目的の値を探す方法で、データの並び順を問わない。
⚠ 2分探索と比べ、前提条件が「なし」、計算量が n。頻度順に並べた表はこちらで探す。
2分探索 にぶんたんさく
整列済みのデータの中央と比べ、探す範囲を毎回半分に絞っていく探索方法。
⚠ 線形探索と違い、キーで整列済みであることが前提。計算量は log₂n(n log₂n ではない)。
ハッシュ探索 はっしゅたんさく
キーから計算したハッシュ値を格納位置として使い、目的のデータを直接取り出す探索方法。
⚠ 2分探索と違い整列は不要。衝突を無視すれば計算量は 1(定数)。
ハッシュ値 はっしゅち
キーを決まった計算式(ハッシュ関数)に通して得られる、格納位置を表す値。
衝突 しょうとつ
異なるキーから同じハッシュ値が出て、格納位置が重なること(シノニムとも呼ぶ)。
⚠ 試験の計算量の問題では「衝突は無視できる」と条件が付き、そのときハッシュ探索は 1 になる。
整列(ソート) せいれつ
データをキーの昇順や降順に並べ替えること。
⚠ 2分探索の前提条件。整列処理自体の計算量は n log₂n や n² で、探索の log₂n と混同しない。
計算量 けいさんりょう
データ数 n が増えたとき、処理の手間(比較回数や時間)がどのように増えるかを表す尺度。
オーダ order(O記法)
計算量の増え方を、定数倍を無視して n、log₂n、n² などの形だけで表したもの。
⚠ 「n² のオーダ」は cn²(c は定数)で抑えられる意味。具体的な回数そのものではない。
log₂n ログにエヌ
2 を何乗すると n になるかを表す値で、n を半分にし続けて 1 になるまでの回数に当たる。
⚠ n log₂n(整列の計算量)と取り違えやすい。1件探すだけなら log₂n。
添字 そえじ
配列の何番目の要素かを表す番号で、A(m) の m に当たる。
流れ図 ながれず(フローチャート)
処理の手順を、処理・判定・ループの記号と矢印でつないで表した図。
平均比較回数 へいきんひかくかいすう
いろいろな探す値について比較回数を平均した期待値で、線形探索なら候補数の約半分になる。
⚠ 最悪比較回数(最後まで調べたときの回数)と取り違えやすい。問題文が「平均」か「最大」かを必ず確認する。
ブロック分割探索 ぶろっくぶんかつたんさく
整列済みデータを一定件数のブロックに分け、ブロックを特定してからその中を探す2段階の探索方法。

このレッスンの過去問

このレッスンで稽古する