1. unsorted array
  2. already sorted
  3. reverse sorted
  4. with duplicates
  5. single element
  6. two elements unsorted
コース一覧
コンピューターサイエンス入門:理論編
バブルソート

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

バブルソート

バブルソート

隣同士しか見ないのに、全体が並ぶ

並べ替えというと、全体を見渡していちばん小さいものを探して、という手順を思い浮かべます。ところが 隣り合う 2 つだけを見て、順番が逆なら入れ替える という操作を繰り返すだけでも、配列はきちんと並びます。視野は常に 2 つ分しかないのに、全体が整っていくところが面白いところです。

その代わり、1 周では終わりません。何周も往復することになり、その周の数が O(n^2) の正体です。

入れ替えは、退避してから

2 つの値を入れ替える書き方から確認します。

Python

x = 3 y = 8 x, y = y, x print(x, y) # 8 3

Python や Go は同時代入で 1 行です。JavaScript や Java では一時変数を経由します。ここでうっかり x = y を先に書くと x の元の値が上書きされて消え、両方が 8 になります。入れ替えは必ず「片方を退避してから」です。

1 周まわすと、右端が 1 つ確定する

[5, 1, 4, 2, 8] を左から隣同士で比べ、逆なら入れ替えます。1 周終わると、いちばん大きい 8 が右端に来ています。2 周目は、確定した右端を除いた範囲でやり直します。

周終わったときの並び入れ替えた回数
1 周目1 4 2 5 83
2 周目1 2 4 5 81
3 周目1 2 4 5 80

見てほしいのは右の列です。3 回、1 回、0 回と減っています。周を重ねるほど並びが整っていくので、入れ替える必要そのものが減っていきます。逆に、最初から並んでいる配列を渡すと、1 周目からいきなり 0 回です。まったく逆順の配列なら、毎周ずっと入れ替え続けることになります。

入れ替えが 0 だった周が、終わりの合図

入れ替えが 1 度も起きなかったということは、隣同士がすべて正しい順序だったということです。それはもう並び終わっている、という意味に他なりません。

Python

swapped = False # 1 周のあいだに 1 度でも入れ替えたら swapped = True にする if not swapped: print("もう並んでいる")

この見張りを 1 つ足すだけで、ほぼ並んでいる配列からは早く抜けられます。ただし比べる回数は減りません。1 周目に n - 1 回、2 周目に n - 2 回と比べていくので、最悪の合計は次のようになります。

Python

n = 5 print(n * (n - 1) // 2) # 10

n = 1000 なら約 50 万回、n = 10000 なら約 5000 万回です。入れ替えは減っても、比べる回数は 2 乗で増え続けます。

解説

渡された配列をその場で並べ替えてよいかは、先に決めてください。手元で書き換えると、呼び出した側が持っている配列も一緒に変わります。

要件

  1. バブルソート (隣接要素を比較・交換) のロジックで実装すること
  2. 組み込みの sorted() や Array.prototype.sort は使わない
  3. 戻り値は昇順に並んだ配列

入出力例

bubbleSort([5,2,4,6,1,3]) → [1,2,3,4,5,6] bubbleSort([1,2,3,4,5]) → [1,2,3,4,5] bubbleSort([5,4,3,2,1]) → [1,2,3,4,5] bubbleSort([3,1,2,3,1]) → [1,1,2,3,3] bubbleSort([7]) → [7] bubbleSort([2,1]) → [1,2]

ヒント

外側ループ i を 0..n-1 まわし、内側ループ j を 0..n-i-2 までまわす

a[j] > a[j+1] なら swap する。Python は a[j], a[j+1] = a[j+1], a[j] でワンライナー

元の配列を破壊したくないなら list(arr) や [...arr] でコピーしてから処理する

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 配列の最大と最小

    配列の最大値と最小値を 1 回のスキャンで求める。O(n) で全要素を見る典型例。

  • 累積和で範囲合計

    累積和 (prefix sum) を作っておくことで、範囲合計のクエリを O(1) で答えられる仕組みを学ぶ。

  • 第3章まとめクイズ

    計算量と Big-O、線形探索・二分探索・累積和の理解度を 1 問のクイズで確認する。

  • スタック (push/pop) を実装する

    後入れ先出し (LIFO) の代表選手であるスタックを、push と pop の操作シーケンスで動かす。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 配列サイズ固定の同型データの集まり
  • JavaScriptWeb で動的な振る舞いを担う言語
  • 変数データに名前をつけて参照する仕組み
  • バブルソート隣り合う要素を交換し続ける並べ替え
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

バブルソート

⌘S で保存