Menu
Coddy logo textTech

バブルソート

最終更新

バブルソートはリストを繰り返し走査し、隣り合う各要素のペアを比較して、順序が誤っていれば交換します。1回の完全なパスごとに、残りの最大値が末尾の正しい位置へ「浮かび上がる」ため、各パスは1つ少ない要素だけを見ればよくなります。上の再生を押して比較と交換を観察するか、1ステップずつ進めてください。

最も理解しやすいソートアルゴリズムの1つで、最初に学ぶアルゴリズムとして優れています。ただし実行時間が O(n²) のため、大きな入力には実用的ではありません。

時間計算量と空間計算量

ケース計算量備考
最良ケースO(n)すでにソート済み、早期終了チェックあり
平均ケースO(n²)ランダムな順序
最悪ケースO(n²)逆順にソート済み
空間O(1)インプレース、一時変数のみ
安定はい等しい要素は相対順序を保つ

ステップごとの説明

ステップ何が起こるか
1配列の先頭から始める。
2現在の要素を次の要素と比較する。
3順序が誤っていれば交換する。
41つ右へ進め、末尾まで繰り返す(1回のパス)。
5パスを繰り返す。各パスで末尾の要素がもう1つ確定する。
6完全な1パスで交換が起きなくなったら停止する。

具体例

[5, 2, 4, 1] をソートする場合:

パス配列動作
1[2, 4, 1, 5]5,2、次に 5,4、次に 5,1 を交換。5 が末尾へ浮かび上がる。
2[2, 1, 4, 5]2,4 は正しい順序。4,1 を交換。4,5 は正しい順序。4 が確定する。
3[1, 2, 4, 5]2,1 を交換。残りはすでに正しい順序。2 が確定する。
4[1, 2, 4, 5]完全な1パスで交換が起きないため、配列はソート済みでアルゴリズムは停止する。

バブルソートを使うべき場面

使うべきとき避けるべきとき
比較ソートの仕組みを教える、または学ぶときO(n²) が遅すぎる大きな入力をソートするとき
入力がごく小さい、またはほぼソート済みのとき(早期終了で O(n) に近づく)最速の汎用ソートが必要なとき — quicksort や merge sort を使う
ほとんどコードを書かずに安定でインプレースなソートが欲しいときデータがランダムな順序で、性能が重要なとき
短いリストが1パスですでにソート済みかを検出するとき書き込み回数が多いとコストが高いとき(例:フラッシュメモリ)。選択ソートの方が交換が少ない

Bubble Sortのコード

Python, JavaScript, Java, C++, Cによるクリーンで実行可能なBubble Sortの実装です。言語を選んでコードをコピーするか、Coddyプレイグラウンドに読み込んだ状態で開けます。

PythonでのBubble Sortのコード

Python
1def bubble_sort(a):2    n = len(a)3    for i in range(n - 1):4        swapped = False5        for j in range(n - 1 - i):6            if a[j] > a[j + 1]:7                a[j], a[j + 1] = a[j + 1], a[j]8                swapped = True9        if not swapped:10            break  # no swaps means the list is already sorted11    return a12
13
14nums = [5, 1, 4, 2, 8]15print("Before:", nums)16bubble_sort(nums)17print("After: ", nums)
このコードをPythonプレイグラウンドで実行

バブルソートのよくある質問

バブルソートの時間計算量はどのくらいですか?
バブルソートは入れ子ループのため、平均ケースと最悪ケースで O(n²) の時間で実行されます。早期終了の最適化を使えば、すでにソート済みの配列で O(n) に達することができます。追加空間は O(1) です。
バブルソートは安定ですか?
はい。バブルソートは隣り合う要素を厳密に順序が誤っているときだけ交換するため、等しい要素が互いを追い越すことはなく、元の相対順序を保ちます。
なぜバブルソートと呼ばれるのですか?
各パスで、未ソートの最大値が泡が水面へ浮かび上がるように一歩ずつ配列の末尾へ移動するため、「バブル(泡)」ソートと呼ばれます。
バブルソートと挿入ソートの違いは何ですか?
どちらも O(n²) で実行され、安定かつインプレースですが、データの動かし方が異なります。バブルソートは順序が誤った隣接ペアを繰り返し交換し、挿入ソートは各要素を取り出してソート済みの前半部分の正しい位置へ滑り込ませます。挿入ソートは通常書き込み回数が少なく、特にほぼソート済みのデータでは実際に高速です。
quicksort ではなくバブルソートを使うべきなのはいつですか?
実際のワークロードではほぼありません。quicksort の平均時間 O(n log n) は、ごく小さな入力を除けばバブルソートの O(n²) を圧倒します。バブルソートが役立つのは、リストが非常に小さいかほぼソート済みのとき、または教育目的で可能な限り単純な安定ソートが欲しいときだけです。
早期終了の最適化はバブルソートの最悪ケースを変えますか?
いいえ。パスで交換が起きたかを記録すると、バブルソートは早く停止でき、すでにソート済みの入力で O(n) に達しますが、逆順にソートされた配列は依然としてすべての比較が必要なため、最悪ケースは O(n²) のままです。この最適化は最良ケースとほぼソート済みのケースにのみ役立ちます。
Coddy programming languages illustration

Coddy でアルゴリズムをマスターしよう

始める