Sortowanie bąbelkowe (bubble sort)
Ostatnia aktualizacja
Sortowanie bąbelkowe wielokrotnie przechodzi przez listę, porównuje każdą parę sąsiednich elementów i zamienia je, jeśli są w złej kolejności. Po każdym pełnym przebiegu największa pozostała wartość "wypływa" jak bąbelek na swoje miejsce na końcu, więc każdy kolejny przebieg sprawdza o jeden element mniej. Kliknij odtwarzanie powyżej i zobacz porównania i zamiany albo przechodź przez nie po jednym.
To jeden z najłatwiejszych do zrozumienia algorytmów sortowania, dlatego świetnie nadaje się na pierwszy algorytm, ale czas działania O(n²) czyni go niepraktycznym dla dużych danych.
Złożoność czasowa i pamięciowa
| Przypadek | Złożoność | Uwagi |
|---|---|---|
| Najlepszy przypadek | O(n) | Już posortowane, ze sprawdzeniem wczesnego wyjścia |
| Średni przypadek | O(n²) | Losowa kolejność |
| Najgorszy przypadek | O(n²) | Posortowane odwrotnie |
| Pamięć | O(1) | W miejscu, tylko zmienna tymczasowa |
| Stabilne | Tak | Równe elementy zachowują względną kolejność |
Krok po kroku
| Krok | Co się dzieje |
|---|---|
| 1 | Zacznij od początku tablicy. |
| 2 | Porównaj bieżący element z następnym. |
| 3 | Jeśli są w złej kolejności, zamień je. |
| 4 | Przesuń się o jedną pozycję w prawo i powtarzaj do końca (jeden przebieg). |
| 5 | Powtarzaj przebiegi; każdy ustala kolejny element na końcu. |
| 6 | Zakończ, gdy pełny przebieg nie wykona żadnej zamiany. |
Przykład krok po kroku
Sortowanie [5, 2, 4, 1]:
| Przebieg | Tablica | Działanie |
|---|---|---|
| 1 | [2, 4, 1, 5] | Zamień 5,2, potem 5,4, potem 5,1; 5 wypływa na koniec. |
| 2 | [2, 1, 4, 5] | 2,4 w porządku; zamień 4,1; 4,5 w porządku; 4 jest na miejscu. |
| 3 | [1, 2, 4, 5] | Zamień 2,1; reszta jest już w porządku; 2 jest na miejscu. |
| 4 | [1, 2, 4, 5] | Pełny przebieg nie wykonuje zamian, więc tablica jest posortowana i algorytm się kończy. |
Kiedy używać sortowania bąbelkowego
| Używaj, gdy | Unikaj, gdy |
|---|---|
| Uczysz (się), jak działają sortowania przez porównania | Sortujesz duże dane, dla których O(n²) jest zdecydowanie za wolne |
Dane są malutkie lub prawie posortowane (z wczesnym wyjściem zbliża się do O(n)) | Potrzebujesz najszybszego sortowania ogólnego przeznaczenia: użyj quicksorta lub merge sort |
| Potrzebujesz stabilnego sortowania w miejscu przy minimalnej ilości kodu | Dane mają losową kolejność, a liczy się wydajność |
| Chcesz w jednym przebiegu sprawdzić, czy krótka lista jest już posortowana | Wiele zapisów jest kosztownych (np. pamięć flash); sortowanie przez wybieranie wykonuje mniej zamian |
Bubble Sort: kod
Przejrzysta, gotowa do uruchomienia implementacja algorytmu Bubble Sort w językach: Python, JavaScript, Java, C++, C, Pseudocode. Wybierz język, skopiuj kod albo otwórz go od razu w edytorze online Coddy.
Bubble Sort: kod (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)Bubble Sort: kod (JavaScript)
1function bubbleSort(a) {2 for (let end = a.length - 1; end > 0; end--) {3 let swapped = false;4 for (let j = 0; j < end; j++) {5 if (a[j] > a[j + 1]) {6 [a[j], a[j + 1]] = [a[j + 1], a[j]];7 swapped = true;8 }9 }10 if (!swapped) break; // Already sorted: stop early11 }12 return a;13}14
15const data = [5, 2, 9, 1, 7, 3];16console.log("Before:", data);17console.log("Sorted:", bubbleSort([...data]));Bubble Sort: kod (Java)
1import java.util.Arrays;2
3public class Main {4 static void bubbleSort(int[] arr) {5 for (int i = arr.length - 1; i > 0; i--) {6 boolean swapped = false;7 for (int j = 0; j < i; j++) {8 if (arr[j] > arr[j + 1]) {9 int tmp = arr[j];10 arr[j] = arr[j + 1];11 arr[j + 1] = tmp;12 swapped = true;13 }14 }15 if (!swapped) break; // already sorted16 }17 }18
19 public static void main(String[] args) {20 int[] arr = {5, 1, 4, 2, 8, 3};21 System.out.println("Before: " + Arrays.toString(arr));22 bubbleSort(arr);23 System.out.println("After: " + Arrays.toString(arr));24 }25}Bubble Sort: kod (C++)
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10void bubbleSort(std::vector<int>& a) {11 for (size_t pass = 0; pass + 1 < a.size(); ++pass) {12 bool swapped = false;13 // Each pass bubbles the largest remaining value to the end14 for (size_t j = 0; j + 1 < a.size() - pass; ++j) {15 if (a[j] > a[j + 1]) {16 std::swap(a[j], a[j + 1]);17 swapped = true;18 }19 }20 if (!swapped) break; // already sorted21 }22}23
24int main() {25 std::vector<int> data = {5, 1, 4, 2, 8, 3};26 std::cout << "Before: ";27 printVec(data);28 bubbleSort(data);29 std::cout << "After: ";30 printVec(data);31 return 0;32}Bubble Sort: kod (C)
1#include <stdbool.h>2#include <stdio.h>3
4void printArr(const int a[], int n) {5 for (int i = 0; i < n; i++) printf("%d ", a[i]);6 printf("\n");7}8
9void bubbleSort(int a[], int n) {10 for (int pass = 0; pass < n - 1; pass++) {11 bool swapped = false;12 // Each pass bubbles the largest remaining value to the end13 for (int j = 0; j < n - 1 - pass; j++) {14 if (a[j] > a[j + 1]) {15 int tmp = a[j];16 a[j] = a[j + 1];17 a[j + 1] = tmp;18 swapped = true;19 }20 }21 if (!swapped) break; // already sorted22 }23}24
25int main(void) {26 int data[] = {5, 1, 4, 2, 8, 3};27 int n = sizeof(data) / sizeof(data[0]);28 printf("Before: ");29 printArr(data, n);30 bubbleSort(data, n);31 printf("After: ");32 printArr(data, n);33 return 0;34}Bubble Sort: kod (Pseudocode)
1DECLARE nums : ARRAY[1:7] OF INTEGER2DECLARE n : INTEGER3n ← 74nums[1] ← 75nums[2] ← 36nums[3] ← 97nums[4] ← 18nums[5] ← 59nums[6] ← 810nums[7] ← 211DECLARE i : INTEGER12DECLARE j : INTEGER13DECLARE temp : INTEGER14
15// Bubble the largest remaining value to the end on each pass16FOR i ← 1 TO n - 117 FOR j ← 1 TO n - i18 IF nums[j] > nums[j + 1] THEN19 temp ← nums[j]20 nums[j] ← nums[j + 1]21 nums[j + 1] ← temp22 ENDIF23 NEXT j24NEXT i25
26FOR i ← 1 TO n27 OUTPUT nums[i]28NEXT iSortowanie bąbelkowe: najczęstsze pytania
Jaka jest złożoność czasowa sortowania bąbelkowego?
O(n²) w średnim i najgorszym przypadku z powodu zagnieżdżonych pętli. Z optymalizacją wczesnego wyjścia może osiągnąć O(n) dla już posortowanej tablicy. Zużywa O(1) dodatkowej pamięci.Czy sortowanie bąbelkowe jest stabilne?
Skąd nazwa sortowanie bąbelkowe?
Czym różni się sortowanie bąbelkowe od sortowania przez wstawianie?
O(n²), są stabilne i sortują w miejscu, ale inaczej przenoszą dane: sortowanie bąbelkowe wielokrotnie zamienia sąsiednie pary w złej kolejności, a sortowanie przez wstawianie bierze każdy element i przesuwa go na właściwe miejsce w posortowanym początku tablicy. Sortowanie przez wstawianie zwykle wykonuje mniej zapisów i w praktyce działa szybciej, zwłaszcza na prawie posortowanych danych.Kiedy użyć sortowania bąbelkowego zamiast quicksorta?
O(n log n) quicksorta miażdży O(n²) sortowania bąbelkowego dla wszystkiego poza malutkimi danymi. Po sortowanie bąbelkowe warto sięgnąć tylko wtedy, gdy lista jest bardzo mała lub prawie posortowana albo gdy do nauki potrzebujesz najprostszego możliwego stabilnego sortowania.Czy optymalizacja wczesnego wyjścia zmienia najgorszy przypadek sortowania bąbelkowego?
O(n) dla już posortowanych danych, ale tablica posortowana odwrotnie nadal wymaga wszystkich porównań, więc najgorszy przypadek pozostaje O(n²). Optymalizacja pomaga tylko w najlepszym przypadku i przy prawie posortowanych danych.