広告スペース

第30回 ソートアルゴリズム

C言語のソートアルゴリズム。バブル・選択・挿入ソートをアニメーションで可視化。

ソートとは ― データを並び替える

配列のデータを昇順(小さい順)や降順(大きい順)に並べ替える処理をソートと呼びます。検索の高速化やデータ整理の基本技術です。

代表的なソートアルゴリズム

アルゴリズム計算量(平均)特徴
バブルソートO(n²)最も単純。隣同士を比較・交換
選択ソートO(n²)最小値を探して先頭に置く
挿入ソートO(n²)トランプの手札整理と同じ。ほぼ整列済みなら高速
クイックソートO(n log n)実用最速。C標準の qsort() はこれがベース
初心者はまずバブル→選択→挿入の3つを理解しましょう。どれも二重ループで書けるので、forループの復習にもなります。

バブルソート ― 隣同士を比較して交換

配列の隣り合う要素を比較し、順序が逆なら交換。これを繰り返すと大きい値が「泡のように」後ろに浮かび上がっていきます。
void bubbleSort(int a[], int n) {
  for (int i = 0; i < n - 1; i++) {
    for (int j = 0; j < n - 1 - i; j++) {
      if (a[j] > a[j+1]) {
        // 交換(swap)
        int tmp = a[j];
        a[j] = a[j+1];
        a[j+1] = tmp;
      }
    }
  }
}

動きのイメージ

[5 3 8 1 4] → 5>3? swap → [3 5 8 1 4]
[3 5 8 1 4] → 5>8? no → [3 5 8 1 4]
[3 5 8 1 4] → 8>1? swap → [3 5 1 8 4]
[3 5 1 8 4] → 8>4? swap → [3 5 1 4 8] ← 8が確定!
... 以下、残りの要素で繰り返す
計算量
O(n²) — 要素数が増えると急激に遅くなる
メリット
実装が最もシンプル。教育向き。

選択ソート ― 最小値を見つけて先頭に

未整列部分から最小値を探し、先頭と交換する。これを繰り返す。
void selectionSort(int a[], int n) {
  for (int i = 0; i < n - 1; i++) {
    int minIdx = i;
    for (int j = i + 1; j < n; j++) {
      if (a[j] < a[minIdx])
        minIdx = j;      // 最小値の位置を記録
    }
    // i番目と最小値を交換
    int tmp = a[i];
    a[i] = a[minIdx];
    a[minIdx] = tmp;
  }
}

動きのイメージ

[5 3 8 1 4] → 最小=1 → swap(5,1) → [1 3 8 5 4]
[1 3 8 5 4] → 最小=3 → そのまま → [1 3 8 5 4]
[1 3 8 5 4] → 最小=4 → swap(8,4) → [1 3 4 5 8]
[1 3 4 5 8] → 最小=5 → そのまま → [1 3 4 5 8] 完了!
計算量
O(n²) — バブルと同じだが交換回数は少ない
メリット
データの移動回数が最小限。わかりやすいアルゴリズム。

挿入ソート ― トランプの手札整理

左端を「整列済み」とし、右の要素を1つずつ正しい位置に挿入していく。トランプを手札に加えるときの動作と同じ。
void insertionSort(int a[], int n) {
  for (int i = 1; i < n; i++) {
    int key = a[i];      // 挿入する値
    int j = i - 1;
    while (j >= 0 && a[j] > key) {
      a[j+1] = a[j];    // 右にずらす
      j--;
    }
    a[j+1] = key;        // 正しい位置に挿入
  }
}

動きのイメージ

[5| 3 8 1 4] → 3を挿入 → [3 5| 8 1 4]
[3 5| 8 1 4] → 8はそのまま → [3 5 8| 1 4]
[3 5 8| 1 4] → 1を先頭に → [1 3 5 8| 4]
[1 3 5 8| 4] → 4を3と5の間に → [1 3 4 5 8] 完了!
| の左が整列済み部分。
計算量
O(n²)(最悪)/ O(n)(ほぼ整列済みなら最速!)
メリット
少量データやほぼソート済みデータに強い。安定ソート。

ソート可視化デモ

アルゴリズムを選んで「開始」を押すと、配列が並び替わる過程をアニメーションで確認できます。
「開始」を押すとアニメーションが始まります。
比較回数: 0 交換回数: 0
広告スペース

関連する講座

繰り返し・配列・文字列
第18回 配列
C言語の配列の宣言・初期化・アクセス方法。メモリ配置も図解。
アルゴリズム編
第29回 データ構造入門
C言語で学ぶデータ構造。連結リスト・スタック・キューの実装と可視化。
繰り返し・配列・文字列
第14回 繰り返し(for/while)
C言語のfor文とwhile文の使い方。ループ処理を図解で解説。
← 前の講座
第29回 データ構造入門
次の講座 →
第31回 コンパイルエラー辞典

よくある質問(FAQ)

Q. 結局、最も速いソートアルゴリズムは?

A. 一般的にはQuickSort(クイックソート)が最速です。平均時間計算量は O(n log n) で、実装も効率的です。ただしデータの特性に応じて、MergeSort(マージソート)やHeapSort(ヒープソート)の方が速い場合もあります。プロの実装では用途に合わせて使い分けます。

Q. どのソートアルゴリズムをいつ使う?

A. バブルソートは教育用、挿入ソートはほぼソート済みデータに有効、クイックソートは一般的用途(標準ライブラリqsort()で採用)、マージソートはリスト構造や外部ソートに使います。学習初期はバブルソート→挿入ソート→クイックソートの順に習うのが効果的です。

Q. 安定ソート(stable sort)って何?

A. 安定ソートは「同じ値を持つ要素の相対的な位置が変わらないソート」です。例えば学生を点数でソートする際、同じ点数なら元の順序が保たれるのが安定です。安定: バブル・挿入・マージ ソート。不安定: 選択・クイック・ヒープソート。

Q. O(n log n)とかの時間計算量って何?

A. 時間計算量は「データサイズnに対する処理時間の増加傾向」を表します。O(n²)は n が10倍になると処理時間は100倍、O(n log n)なら約33倍です。O(n)が線形、O(n log n)が実用的な高速、O(n²)以上は小規模向けです。

確認クイズ

この講座の理解度をチェックしましょう!

Q1. バブルソートの時間計算量(最悪)は?

O(n)
O(n log n)
O(n²)

バブルソートは隣接要素を繰り返し比較・交換するため、最悪の場合 O(n²) の時間がかかります。

Q2. クイックソートの平均時間計算量は?

O(n)
O(n log n)
O(n²)

クイックソートはピボットで分割統治するため、平均 O(n log n) で高速です。ただし最悪の場合は O(n²) になります。

Q3. 安定ソート(stable sort)とは?

クラッシュしないソート
同じ値の要素の順序が保たれるソート
常に最速のソート

安定ソートでは、同じキーを持つ要素の相対的な順序がソート後も維持されます。マージソートは安定、クイックソートは不安定です。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。丁寧な解説で基礎を固められます。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で、演習問題も充実。大学の教科書としても採用多数。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。基礎を終えた後のステップアップに最適。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。