体系学習
アルゴリズムの計算量とオーダー記法を読み解く
入力サイズと処理量の増え方に注目し、O(1)、O(log n)、O(n)、O(n log n)、O(n²)と探索・整列アルゴリズムの関係を理解する。
対象資格:基本情報技術者試験
目安時間:30分
このページで理解できること
- 時間計算量が入力サイズに対する処理量の増え方を表すことを説明できる
- オーダー記法で定数倍や低次項を無視する理由を説明できる
- O(1)、O(log n)、O(n)、O(n log n)、O(n²)の増え方を比較できる
- 単純なループや入れ子ループから時間計算量を判断できる
- 線形探索と二分探索の計算量と前提条件を説明できる
- 代表的な整列アルゴリズムの計算量を大まかに比較できる
- 最悪・平均・最良計算量が入力状態によって異なる場合があることを理解する
基本情報技術者試験:計算量を実測時間そのものと混同せず、入力サイズnに対する処理回数の増え方として捉え、オーダー記法、基本的なループ構造、探索・整列アルゴリズムの時間計算量を判断できる状態を目標にする。
計算量は、プログラムが何秒で終わるかを直接表すものではありません。入力サイズが大きくなったときに、必要な処理量がどのような割合で増えるかを見る尺度です。FEでは、オーダー記法を使ってアルゴリズムを比較し、単純なコードや探索・整列処理から時間計算量を読み取れることが重要です。
まずは計算量を求める手順
細かな命令数を全部数えるのではなく、入力サイズに対して増え方を支配する部分を見ます。
入力サイズnを決める
配列要素数やデータ件数など、問題の大きさを表す量をnとします。
主要な処理回数を見る
比較・代入・ループ本体など、nとともに増える処理を確認します。
nに対する式を作る
n、n²、log nなど、処理回数の増え方を式として捉えます。
支配項を残す
大きなnで増え方を支配する項を残し、定数倍や低次項を無視します。
オーダーで表す
O(n)、O(n²)などとしてアルゴリズムの増加率を表します。
前提条件も確認する
平均・最悪のどれか、データが整列済みかなど、計算量が成立する条件を確認します。
1. 計算量は「実行時間そのもの」ではなく増え方を見る
同じO(n)でもCPUや言語によって実際の秒数は変わります。
時間計算量は、入力サイズnが増えたとき、アルゴリズムが必要とする基本処理の回数がどの程度増えるかを表します。
実際の実行時間はCPU、メモリ、プログラム言語、コンパイラ、データ配置などに左右されます。そのためO(n)だから必ず何ミリ秒で終わる、という意味ではありません。
計算量の利点は、環境依存の秒数ではなく、入力が大きくなったときの伸び方を比較しやすいことです。
空間計算量は必要な追加メモリ量の増え方を表す別の尺度です。FEの現行シラバスでは時間計算量が代表用語ですが、アルゴリズム評価では時間とメモリの両面を考える場合があります。
2. O記法では定数倍と低次項を落として支配的な増え方を見る
3n+10ならO(n)、2n²+5n+1ならO(n²)と考えます。
入力サイズnが十分大きいとき、増加率を支配する項に注目します。例えば3n+10ではnの項が支配的なのでO(n)、2n²+5n+1ではn²が支配的なのでO(n²)と表します。
定数倍を無視するのは、nが大きくなったときに2nと100nがどちらもnに比例して増えるという性質を比較したいからです。実際の実行時間では定数倍も無視できない場合があります。
対数の底は定数倍の違いになるため、漸近的なBig OではO(log₂n)もO(log₁₀n)もO(log n)と表せます。
Big Oは『常に正確にこの回数で実行される』という等式ではなく、入力増加に対する代表的な上界の増え方を表す記法として読みます。
3. よく出る増え方を順番で覚える
大きなnでは、O(1) < O(log n) < O(n) < O(n log n) < O(n²) の順に増えます。
O(1)は入力サイズが増えても主要な処理回数がほぼ一定の処理です。添字を指定した配列アクセスなどが代表例です。
O(log n)は、1回処理するたびに対象範囲を半分にするような処理で現れます。二分探索が代表例です。
O(n)は全要素を一度ずつ確認するような処理、O(n²)はn回の処理をさらにn回繰り返す単純な二重ループなどで現れます。
O(n log n)は、問題を分割しながら各段階で全体に近い量の処理を行う効率的な整列アルゴリズムなどで現れます。
| オーダー | nを2倍にしたときの概略 | 代表例 |
|---|---|---|
| O(1) | ほぼ変化しない | 添字指定の単純な配列アクセス |
| O(log n) | 少しだけ増える | 二分探索 |
| O(n) | 約2倍 | 線形探索 |
| O(n log n) | 2倍よりやや大きく増える | マージソートなど |
| O(n²) | 約4倍 | 単純な二重ループ、選択ソートなど |
4. ループは「何回回るか」を掛け算・足し算で見る
連続する処理は足し、入れ子で独立に回る処理は掛けます。
n回繰り返す一重ループの本体がO(1)なら、全体はO(n)です。
外側がn回、内側も各回n回実行される単純な二重ループなら、処理回数はn×nでO(n²)です。
O(n)の処理の後に別のO(n²)処理を実行する場合、合計はO(n+n²)ですが、大きなnではn²が支配するためO(n²)とします。
ループ変数を毎回2倍にする、あるいは対象を毎回半分にする処理では、nへ到達するまでの回数はおおよそlog₂n回なのでO(log n)になります。
| 処理構造 | 回数の考え方 | 計算量 |
|---|---|---|
| forをn回 | n | O(n) |
| n回×n回の二重ループ | n² | O(n²) |
| O(n)の後にO(n²) | n+n² | O(n²) |
| 対象を毎回半分 | log₂n | O(log n) |
5. 線形探索と二分探索は前提条件までセットで覚える
二分探索が速いのは、探索範囲を毎回半分にできるからです。
線形探索は先頭から順に調べるため、最悪の場合はn個すべてを確認します。最悪時間計算量はO(n)です。
二分探索は、整列済みのデータに対して中央要素と比較し、次に調べる範囲を半分へ絞ります。そのため最悪でも比較回数はおおよそlog₂nに比例し、O(log n)です。
ただし二分探索を使うには、探索対象が順序付けられていて、中央付近の要素へ効率よくアクセスできることなどの前提があります。未整列データへそのまま適用することはできません。
一度だけ探索するために毎回ソートするなら、ソートに掛かるコストも含めて全体の処理量を考える必要があります。
6. 整列アルゴリズムは「常に同じ計算量」とは限らない
代表的な最悪・平均計算量と、入力状態への依存を区別します。
選択ソートは、未整列部分から最小値などを探す処理を繰り返すため、代表的な時間計算量はO(n²)です。バブルソートも単純な実装ではO(n²)として扱われます。
マージソートはデータを分割し、それぞれを整列してマージする分割統治法のアルゴリズムで、時間計算量はO(n log n)です。
クイックソートは平均的にはO(n log n)ですが、分割の偏り方によって最悪O(n²)になる場合があります。
『ソートはO(n log n)』のように一括りにせず、アルゴリズムと、平均・最悪などどのケースを述べているかを確認します。
| アルゴリズム | 代表的な時間計算量 | 注意 |
|---|---|---|
| 選択ソート | O(n²) | 比較回数は入力状態で大きく改善しにくい |
| バブルソート | O(n²) | 単純実装の代表的評価 |
| マージソート | O(n log n) | 追加領域を使う代表的な分割統治法 |
| クイックソート | 平均O(n log n)、最悪O(n²) | 分割の偏りで最悪計算量が悪化する |
7. 最良・平均・最悪のどれを問われているか確認する
同じアルゴリズムでも入力によって処理回数が変わることがあります。
線形探索では、目的の値が先頭にあれば最良ではほぼ一定回数ですが、末尾や存在しない場合は最悪でn件を確認します。
アルゴリズムの説明でO(n)とだけ書かれている場合でも、どのケースを評価しているかを文脈から確認します。試験問題では『最悪の場合』『平均的に』などの条件が示されることがあります。
計算量を比較するときは、入力サイズnの定義も確認します。例えば行列の一辺をnとする場合と、全要素数をnとする場合では式の意味が変わります。
基本情報ではここまでつなげる
- 時間計算量と実測時間を区別できる
- 定数倍・低次項を無視して支配項からO記法を判断できる
- O(1)、O(log n)、O(n)、O(n log n)、O(n²)を増加率順に並べられる
- 一重・二重ループや半減処理の計算量を判断できる
- 線形探索O(n)と二分探索O(log n)の違いと前提条件を説明できる
- 選択ソート・マージソート・クイックソートの代表的な計算量を区別できる
- 最良・平均・最悪のどのケースを評価しているか確認できる
最後に「nが増えたらどう増えるか」へ戻す
- 実行秒数ではなく入力サイズに対する処理量の増え方を見る
- 定数倍と低次項を落として支配項を残す
- 半減を繰り返す処理はlog n、全件走査はn、単純な二重走査はn²になりやすい
- 二分探索は整列済みデータという前提がある
- アルゴリズムによって平均と最悪の計算量が異なる場合がある
- 全体計算量は前処理やソートなど必要な処理も含めて判断する
計算量は公式の暗記より、コードや処理の中で『nに応じて何回実行されるか』を数える習慣を付けると安定します。