Sortowanie bąbelkowe krok po kroku i jego koszt O(n²)

Tymoteusz Kowalski • 13 listopada 2026
Wykres ilustruje algorytm sortowania bąbelkowego, pokazując kolejne kroki i zamiany elementów.

Spis treści

Masz listę [5, 1, 4, 2, 8] i chcesz zobaczyć, jak liczby same ustawiają się rosnąco? W sortowaniu bąbelkowym porównujesz sąsiadów i zamieniasz ich miejscami, gdy stoją w złej kolejności, choć przy dłuższej liście liczba takich kroków szybko rośnie.

Ilustracja pokazuje algorytm sortowania bąbelkowego (bubble sort). Liczby 100 i 45 są porównywane, a strzałka wskazuje ich zamianę.

Sortowanie bąbelkowe najlepiej objaśnia zamiany sąsiednich elementów

  • Jeden przebieg przesuwa największy z nieuporządkowanych elementów na koniec listy.
  • Wczesne zatrzymanie pozwala zakończyć algorytm, gdy cały przebieg nie wymagał zamiany.
  • Średni i najgorszy przypadek wymagają czasu rzędu O(n²).
  • Python ma wbudowane sortowanie przeznaczone do zwykłej pracy z listami.

Po każdym przebiegu jedna liczba trafia na właściwe miejsce

Wyobraź sobie rząd kart z liczbami. Przesuwasz się od lewej do prawej, porównując dwie sąsiednie karty; jeśli lewa ma większą wartość, zamieniasz je. Po pierwszym przejściu największa liczba ląduje na końcu, więc przy następnym przebiegu ten fragment można już pominąć.

Dla listy [5, 1, 4, 2, 8] pierwszy przebieg daje [1, 4, 2, 5, 8], a drugi [1, 2, 4, 5, 8]. Kolejny przebieg nie wykrywa żadnej pary do zamiany, więc zoptymalizowana wersja może przerwać pracę. Ten warunek końca jest łatwy do przeoczenia.

Flaga zamiany oszczędza przebiegi, ale nie ratuje trudnych danych

Bez flagi algorytm może wykonywać kolejne przebiegi nawet wtedy, gdy lista jest już uporządkowana. Zmienna zamieniono zapamiętuje, czy w danym przejściu nastąpiła choć jedna zamiana. Gdy pozostaje fałszywa, wynik jest gotowy.

def bubble_sort(lista):
    wynik = lista.copy()
    n = len(wynik)

    for koniec in range(n - 1, 0, -1):
        zamieniono = False

        for i in range(koniec):
            if wynik[i] > wynik[i + 1]:
                wynik[i], wynik[i + 1] = wynik[i + 1], wynik[i]
                zamieniono = True

        if not zamieniono:
            break

    return wynik

Kopia sprawia, że funkcja zwraca posortowaną listę, a oryginał pozostaje bez zmian. Porównanie używa >, a nie >=: elementy o równych kluczach nie przeskakują nawzajem, co zachowuje ich pierwotną kolejność.

Lista pięciu liczb pokazuje, skąd bierze się koszt O(n²)

W przykładzie z początku algorytm wykonuje 9 porównań i 4 zamiany, zanim przebieg bez zamiany potwierdzi koniec sortowania. To mała lista, więc liczby operacji wyglądają niewinnie. Przy odwróconej kolejności niemal każda para sąsiadów wymaga poprawienia, a pętla przechodzi przez listę wielokrotnie.

Dla listy już uporządkowanej wersja z flagą kończy pracę po jednym przejściu, czyli wykonuje n−1 porównań. Nie zmienia to jednak obrazu dla danych losowych lub odwróconych: średni i najgorszy przypadek pozostają kwadratowe, O(n²). Właśnie dlatego sam korzystny przypadek nie wystarcza, by uznać tę metodę za szybką.

Do nauki wybierz bąbelki, do sortowania w Pythonie użyj wbudowanej metody

Sortowanie bąbelkowe jest czytelne, bo każda zmiana wynika z lokalnego porównania. Uważam, że jego najlepszym zastosowaniem jest ćwiczenie pętli, indeksów i analizy kosztu, a nie porządkowanie większych zbiorów w gotowym programie.

W codziennym kodzie Pythona wybierz sorted(dane), jeśli potrzebujesz nowej listy, albo dane.sort(), jeśli możesz zmienić istniejącą. Dokumentacja Pythona opisuje stabilność sortowania wbudowanego i podkreśla, że używany algorytm potrafi korzystać z już uporządkowanych fragmentów danych. To praktyczniejszy wybór niż ręczna implementacja, gdy celem jest po prostu wynik.

Sytuacja Co z niej wynika Co zrobić
Chcesz prześledzić zamiany krok po kroku Każdy ruch jest łatwy do powiązania z porównaniem sąsiadów Użyj sortowania bąbelkowego jako ćwiczenia
Porządkujesz listę w zwykłym programie Ręczna wersja wykonuje wiele porównań dla większych danych Wybierz sorted() albo .sort()
Własna wersja nie kończy pracy na uporządkowanej liście Brakuje warunku zatrzymującego po przebiegu bez zamiany Dodaj flagę i przerwij pętlę, gdy nie wykonano zamiany

Najlepszy test to śledzenie jednej pary aż do końca

Podczas nauki nie patrz wyłącznie na końcową listę. Zapisuj stan po każdym przebiegu i sprawdzaj, czy największy element z nieustawionej części rzeczywiście przesunął się na koniec; wtedy łatwiej wychwycić błędny zakres pętli.

Gdy celem jest działający program, postaw na funkcje wbudowane. Gdy celem jest zrozumienie, dlaczego algorytm sortuje i skąd bierze się jego koszt, kilka ręcznie prześledzonych zamian powie więcej niż samo sprawdzenie gotowego wyniku.

FAQ - Najczęstsze pytania

Algorytm porównuje sąsiednie liczby i zamienia je miejscami, gdy lewa jest większa od prawej. Po pierwszym przebiegu lista ma postać [1, 4, 2, 5, 8], a po drugim [1, 2, 4, 5, 8]. Następny przebieg nie wymaga zamiany, więc wersja z flagą może zakończyć działanie.

Na początku każdego przebiegu ustaw flagę zamieniono na False, a po każdej zamianie zmień ją na True. Jeśli po przejściu całej nieuporządkowanej części flaga nadal jest fałszywa, lista jest już uporządkowana i można przerwać pętlę. Dla uporządkowanej listy oznacza to jeden przebieg i n−1 porównań.

Dla listy [5, 1, 4, 2, 8] algorytm wykonuje 9 porównań i 4 zamiany, zanim przebieg bez zamiany potwierdzi, że sortowanie jest zakończone. W przypadku większych, losowych lub odwróconych danych średni i najgorszy czas działania pozostaje rzędu O(n²).

Własna implementacja sprawdza się jako ćwiczenie z pętli, indeksów i analizy działania algorytmu. Do porządkowania list w zwykłym programie wybierz sorted(dane), aby otrzymać nową listę, albo dane.sort(), aby zmienić istniejącą. Sortowanie bąbelkowe zachowuje kolejność elementów o równych kluczach, ponieważ zamienia elementy tylko wtedy, gdy lewy jest większy.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

python
złożoność obliczeniowa
sortowanie bąbelkowe
stabilność algorytmu
Autor Tymoteusz Kowalski
Tymoteusz Kowalski
Nazywam się Tymoteusz Kowalski i od 7 lat zajmuję się programowaniem, ze szczególnym uwzględnieniem Pythona oraz nowoczesnych technologii. Moja przygoda z programowaniem zaczęła się od fascynacji możliwościami, jakie daje kod, a z czasem przerodziła się w pasję do dzielenia się wiedzą i pomagania innym w zrozumieniu złożonych zagadnień. Interesuje mnie, jak można uprościć trudne tematy, aby były bardziej przystępne dla każdego, niezależnie od poziomu zaawansowania. W moich tekstach staram się dostarczać rzetelne, aktualne i zrozumiałe informacje, a także porównywać różne źródła, aby zapewnić czytelnikom szeroki kontekst. Piszę o praktycznych zastosowaniach Pythona, nowinkach technologicznych oraz najlepszych praktykach programistycznych. Moim celem jest nie tylko przedstawienie teorii, ale także pokazanie, jak można ją zastosować w praktyce, co mam nadzieję, uczyni moją twórczość użyteczną dla każdego, kto pragnie rozwijać swoje umiejętności w programowaniu.

Udostępnij artykuł

Napisz komentarz