Sortowanie szybkie (quicksort)

  • Informatyka
  • Sortowanie szybkie…
  • Partycjonowanie Lomuto…
  • Złożoność Quicksort
  • Wybór pivota Quicksort
  • Algorytm sortowania…

Podcast

Sortowanie, które wstrząsnęło światem: Quicksort i sekrety algorytmów0:00 / 11:13
0:001:00 pozostało

Sortowanie szybkie, znane jako Quicksort, to jeden z najbardziej efektywnych algorytmów sortowania porównawczego. Opracowany przez Tony'ego Hoare'a w 1959 roku, wciąż pozostaje kluczowym narzędziem w informatyce. Jego siła tkwi w paradygmacie „dziel i zwyciężaj”, który polega na dzieleniu problemu na mniejsze, niezależne części, a następnie łączeniu ich posortowanych wyników.

Czym jest Sortowanie Szybkie (Quicksort)?

Quicksort to algorytm, który działa poprzez rekurencyjne dzielenie listy na dwie podlisty. Kluczową operacją jest partycjonowanie (dzielenie).

Algorytm działa w kilku krokach:

  1. Wybór pivota: Z listy elementów do posortowania wybierany jest jeden, nazywany punktem obrotu lub pivotem. Jego wybór ma ogromny wpływ na wydajność.
  2. Partycjonowanie: Elementy listy są przestawiane. Wszystkie elementy mniejsze od pivota trafiają na lewo, a większe na prawo. Pivot znajduje się na swojej ostatecznej pozycji.
  3. Rekurencja: Algorytm wywołuje się dla podlisty po lewej stronie pivota oraz dla podlisty po prawej. Proces trwa, aż podlisty będą jednoelementowe lub puste, czyli posortowane.

Złożoność Czasowa Quicksortu – Analiza Wydajności

Złożoność czasowa Quicksortu to kluczowy aspekt, który warto zrozumieć. Różni się ona znacząco w zależności od przypadku.

Przypadek Średni (Oczekiwany): O(n log n)

Większość zastosowań sortowania szybkiego to przypadek średni. Osiąga on złożoność czasową O(n log n), gdzie n to liczba elementów.

Dzieje się tak, ponieważ:

  • Każde partycjonowanie wymaga liniowego czasu (O(n)).
  • Liczba poziomów rekurencji wynosi logarytm z n (log n).
  • Wynika to z efektywnego dzielenia problemu na mniej więcej równe części.

Przypadek Najgorszy: O(n²)

Najgorszy przypadek występuje, gdy pivot konsekwentnie dzieli listę na bardzo nierówne części. Na przykład, gdy pivot jest zawsze najmniejszym lub największym elementem.

Skutkuje to:

  • n poziomami rekurencji.
  • Każdy poziom wymaga O(n) czasu.
  • Daje to łączną złożoność O(n²).

Przykładem jest sortowanie już posortowanej listy lub posortowanej w odwrotnej kolejności, jeśli jako pivota wybieramy zawsze pierwszy lub ostatni element.

Sprawdź, co już wiesz

Test · 20 pytań · pierwsze 3 za darmo

Pytanie 1 z 30%

Wybór pierwszego lub ostatniego elementu jako pivota w algorytmie Quicksort zawsze gwarantuje złożoność czasową O(n log n), nawet w przypadku posortowanych danych.

Przećwicz to na fiszkach

29 fiszek · pierwsze 3 za darmo, bez konta

1 / 29

Jaka jest oczekiwana złożoność czasowa algorytmu Quicksort?

O(n log n), gdzie n to liczba elementów do posortowania.

Dotknij, aby odwrócić · Przesuń, aby nawigować

Strategie Wyboru Pivota w Quicksort

Wybór pivota ma ogromny wpływ na wydajność sortowania szybkiego, zwłaszcza w kontekście unikania najgorszego przypadku.

Typowe Metody Wyboru Pivota:

  • Pierwszy/Ostatni element: Najprostszy wybór. Prowadzi jednak do O(n²) dla już posortowanych lub odwrotnie posortowanych danych.
  • Środkowy element: Lepszy niż pierwszy/ostatni, ale nadal podatny na specyficzne układy danych.
  • Losowy pivot: Wybór pivota losowo z podlisty. Znacznie zmniejsza prawdopodobieństwo wystąpienia najgorszego przypadku. Jest to często stosowana i skuteczna strategia.
  • Mediana z trzech: Wybór mediany spośród trzech elementów (np. pierwszego, środkowego i ostatniego). Zwiększa szanse na wybranie pivota, który dobrze dzieli listę, minimalizując ryzyko najgorszego przypadku.

Partycjonowanie Lomuto – Szczegółowe Opracowanie

Istnieje kilka schematów partycjonowania. Schemat Lomuto jest jednym z najprostszych do zrozumienia i zaimplementowania.

Zasady Partycjonowania Lomuto

W tym schemacie, zazwyczaj ostatni element podlisty jest wybierany jako pivot. Elementy mniejsze lub równe pivotowi są przenoszone na początek podlisty.

Kroki algorytmu partycjonowania Lomuto:

  1. Wybierz ostatni element podlisty jako pivot.
  2. Zainicjuj indeks i na początek_podlisty - 1. Będzie on wskazywał na ostatni element mniejszy lub równy pivotowi.
  3. Przejdź przez podlistę od początku_podlisty do koniec_podlisty - 1 (czyli do elementu przed pivotem) za pomocą indeksu j.
  4. Jeśli element[j] jest mniejszy lub równy pivotowi:
  • Zwiększ i o 1.
  • Zamień miejscami element[i] i element[j].
  1. Po zakończeniu pętli, zamień miejscami element[i + 1] i pivot (czyli element[koniec_podlisty]).
  2. Zwróć i + 1, czyli ostateczną pozycję pivota.

Pseudokod Algorytmu Quicksort (Partycjonowanie Lomuto)

Oto ogólny pseudokod dla algorytmu sortowania szybkiego z partycjonowaniem Lomuto:

PROCEDURA Quicksort(tablica, początek, koniec):
 JEŻELI początek < koniec:
 pivot_index = Partycjonuj(tablica, początek, koniec)
 Quicksort(tablica, początek, pivot_index - 1)
 Quicksort(tablica, pivot_index + 1, koniec)

PROCEDURA Partycjonuj(tablica, początek, koniec):
 pivot = tablica[koniec] // Wybór ostatniego elementu jako pivota
 i = początek - 1
 DLA j OD początek DO koniec - 1:
 JEŻELI tablica[j] <= pivot:
 i = i + 1
 Zamień(tablica[i], tablica[j])
 Zamień(tablica[i + 1], tablica[koniec]) // Umieść pivota na właściwej pozycji
 ZWRÓĆ i + 1

Przykład Partycjonowania Lomuto

Rozważmy listę [7, 2, 1, 6, 8, 5, 3, 4]. Sortujemy całą listę: początek_podlisty = 0, koniec_podlisty = 7.

  1. Wybór pivota: Ostatni element, 4. Lista: [7, 2, 1, 6, 8, 5, 3, **4**].
  2. Inicjalizacja: i = -1.
  3. Iteracja j:
  • j = 0, element[0] = 7. 7 nie jest ≤ 4.
  • j = 1, element[1] = 2. 2 jest ≤ 4. i staje się 0. Zamień element[0] (7) z element[1] (2). Lista: [**2**, **7**, 1, 6, 8, 5, 3, 4].
  • j = 2, element[2] = 1. 1 jest ≤ 4. i staje się 1. Zamień element[1] (7) z element[2] (1). Lista: [2, **1**, **7**, 6, 8, 5, 3, 4].
  • j = 3, element[3] = 6. 6 nie jest ≤ 4.
  • j = 4, element[4] = 8. 8 nie jest ≤ 4.
  • j = 5, element[5] = 5. 5 nie jest ≤ 4.
  • j = 6, element[6] = 3. 3 jest ≤ 4. i staje się 2. Zamień element[2] (7) z element[6] (3). Lista: [2, 1, **3**, 6, 8, 5, **7**, 4].
  1. Po zakończeniu pętli: i = 2. Zamień element[i + 1] (czyli element[3], wartość 6) z pivotem (element[7], wartość 4).
  • Lista: [2, 1, 3, **4**, 8, 5, 7, **6**].
  1. Zwróć i + 1 = 3. Pivot 4 znajduje się na pozycji 3. Elementy [2, 1, 3] są mniejsze od 4, a [8, 5, 7, 6] są większe od 4.

Quicksort – Typowe Błędy i Problemtyka Implementacji

Podczas implementacji sortowania szybkiego często pojawiają się błędy, które mogą wpływać na jego wydajność lub poprawność.

Najczęstsze Błędy:

  1. Niewłaściwy wybór pivota: Ignorowanie wpływu wyboru pivota może prowadzić do złożoności O(n²) dla wielu praktycznych zestawów danych. To znacznie wolniejsze niż oczekiwane O(n log n).
  2. Błędy w implementacji partycjonowania: Proces partycjonowania jest delikatny. Niewłaściwe zarządzanie indeksami i i j lub błędne umieszczenie pivota może prowadzić do nieskończonych rekurencji lub nieprawidłowego sortowania.
  3. Brak przypadku bazowego rekurencji: Zapomnienie o warunku początek < koniec w funkcji Quicksort spowoduje nieskończoną rekurencję i przepełnienie stosu.

Stabilność Quicksortu

Quicksort nie jest algorytmem stabilnym. Oznacza to, że względna kolejność elementów o równych wartościach może ulec zmianie po sortowaniu. Jest to ważna cecha, którą należy wziąć pod uwagę w niektórych zastosowaniach.

Quicksort w Symulacji Interaktywnej – Lepsze Zrozumienie

Interaktywna symulacja sortowania szybkiego pozwala na wizualizację kluczowego etapu algorytmu – krokowania partycjonowania wokół pivota. Użytkownik może obserwować, jak elementy są przestawiane względem pivota.

Co można zaobserwować w symulacji?

  • Śledzenie indeksów i i j: Jak poruszają się po tablicy i wpływają na zamiany elementów.
  • Pozycję pivota: Jak jest wybierany i gdzie ostatecznie ląduje po partycjonowaniu.
  • Wizualizacja zamian: Kolorowe podświetlenia lub animacje pokazują, które elementy są porównywane i zamieniane.
  • Zrozumienie podziału: Po zakończeniu partycjonowania, symulacja wyraźnie pokazuje dwie podlisty (mniejsze i większe od pivota), które będą dalej sortowane rekurencyjnie.

Krokowanie partycjonowania pomaga zrozumieć, dlaczego Quicksort jest tak wydajny w średnim przypadku i jakie warunki prowadzą do jego najgorszej wydajności. Możesz dowiedzieć się więcej o Quicksort na Wikipedii.

Najczęściej Zadawane Pytania (FAQ)

Czym jest Quicksort w skrócie?

Quicksort to szybki algorytm sortowania, który działa na zasadzie „dziel i zwyciężaj”. Wybiera element zwany pivotem, dzieli listę na elementy mniejsze i większe od pivota, a następnie rekurencyjnie sortuje obie podlisty. Jest to jeden z najczęściej używanych algorytmów.

Dlaczego Quicksort jest szybki w średnim przypadku?

W Quicksort złożoność w średnim przypadku to O(n log n). Wynika to z tego, że algorytm zazwyczaj dzieli listę na mniej więcej równe części. Każde dzielenie wymaga liniowego czasu (O(n)), a liczba podziałów to logarytm z liczby elementów, co daje bardzo efektywne sortowanie.

Kiedy Quicksort działa najgorzej i dlaczego?

Najgorszy przypadek Quicksortu to O(n²). Występuje, gdy pivot jest konsekwentnie wybierany w taki sposób, że dzieli listę bardzo nierówno, np. zawsze jest to najmniejszy lub największy element. Dzieje się tak często przy sortowaniu już posortowanych danych, jeśli pivotem jest zawsze pierwszy lub ostatni element.

Jakie są najlepsze strategie wyboru pivota w Quicksort?

Najlepsze strategie wyboru pivota mają na celu unikanie najgorszego przypadku O(n²). Skuteczne metody to losowy wybór pivota (co zmniejsza prawdopodobieństwo wystąpienia złego podziału) oraz wybór mediany z trzech elementów (np. pierwszego, środkowego i ostatniego), co zwiększa szanse na dobrą pozycję pivota.

Czy Quicksort jest algorytmem stabilnym?

Nie, Quicksort nie jest algorytmem stabilnym. Oznacza to, że jeśli w sortowanej liście występują elementy o tej samej wartości, ich względna kolejność może ulec zmianie po zakończeniu sortowania. W niektórych zastosowaniach stabilność algorytmu sortowania jest kluczowa.

Przećwicz to, nie tylko przeczytaj

29 fiszek, test z wyjaśnieniami i podcast do tego tematu. Konto jest darmowe i zaczynasz tam, gdzie skończyłeś.

  • Bez karty płatniczej
  • Strona i aplikacja mobilna
  • 330 000+ uczniów
Zacznij za darmo

Powiązane tematy