Sortowanie pozycyjne liczb

W tej sekcji zrealizujemy algorytm sortowania pozycyjnego z wykorzystaniem innego stabilnego algorytmu sortowaniasortowanie stabilnestabilnego algorytmu sortowania. Będzie to sortowanie bąbelkowesortowanie bąbelkowesortowanie bąbelkowe, które zostało omówione w e‑materiale Sortowanie bąbelkowe w języku JavaPxgkD2R5YSortowanie bąbelkowe w języku Java.

Specyfikacja:

Dane:

  • A – jednowymiarowa tablica liczb naturalnych; dane do posortowania

Wynik:

  • A – jednowymiarowa tablica liczb naturalnych; posortowane niemalejąco liczby naturalne

Przeanalizujmy przykład przedstawiający zasadę działania algorytmu.

Przykład 1

Naszym zadaniem jest posortowanie niemalejąco zbioru pięciu liczb trzycyfrowych.

A   = { 534 , 123 , 452 , 897 , 342 }

Najpierw, używając dowolnego stabilnego algorytmu sortowania, sortujemy niemalejąco elementy zbioru A, uwzględniając tylko cyfry na pozycji jedności. Potem powtarzamy operację na zmodyfikowanym już zbiorze A, sortując po cyfrach dziesiątek, a następnie setek itd. Grafika przedstawia, jak wygląda zbiór po kolejnych sortowaniach.

RDTnKtjaIV6kv
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Implementacja w języku Java

Teraz możemy przejść do implementacji algorytmu w języku Java. Naszym celem jest napisanie programu, który umożliwi posortowanie dowolnego zbioru liczb naturalnych za pomocą algorytmu sortowania pozycyjnego. Jako pomocniczego stabilnego algorytmu sortowania użyjemy algorytmu sortowania bąbelkowego.

Finalny program ma sortować zadany zbiór liczb pozycyjnie – od pozycji najmniej znaczącej, czyli jedności, do pozycji najbardziej znaczącej. W związku z tym należy napisać funkcję, która znajdzie i zwróci największą liczbę w zadanym zbiorze. Nazwijmy tę funkcję znajdzMax().

Linia 1. static int znajdzMax otwórz nawias okrągły int otwórz nawias kwadratowy zamknij nawias kwadratowy tab zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int max znak równości tab otwórz nawias kwadratowy 0 zamknij nawias kwadratowy średnik. Linia 4. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny tab kropka length średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. if otwórz nawias okrągły tab otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias ostrokątny max zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. max znak równości tab otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 7. zamknij nawias klamrowy. Linia 8. zamknij nawias klamrowy. Linia 10. return max średnik. Linia 11. zamknij nawias klamrowy.

Przyjmuje ona jeden parametr – int[] tab – czyli tablicę zawierającą zbiór liczb naturalnych. To z tego zbioru ma zostać wybrana największa liczba.

Następnie przejdźmy do zadeklarowania kolejnej funkcji – sortowaniePozycyjne(), która będzie odpowiadać za realizację sortowań dla kolejnych pozycji, począwszy od pozycji jedności.

Linia 1. static void sortowaniePozycyjne otwórz nawias okrągły int tab otwórz nawias kwadratowy zamknij nawias kwadratowy zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int max znak równości znajdzMax otwórz nawias okrągły tab zamknij nawias okrągły średnik. Linia 4. for otwórz nawias okrągły int poz znak równości 1 średnik max prawy ukośnik poz zamknij nawias ostrokątny 0 średnik poz asterysk znak równości 10 zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. sortowanieBabelkowe otwórz nawias okrągły tab przecinek poz zamknij nawias okrągły średnik. Linia 6. zamknij nawias klamrowy. Linia 7. zamknij nawias klamrowy.

Za pomocą wcześniej utworzonej funkcji znajdzMax(), szukamy największej liczby w zadanym zbiorze do posortowania i zapisujemy ją do zmiennej max.

Następnie deklarujemy pętlę for, która wykona tyle iteracjiiteracjaiteracji, ile posiada cyfr największa liczba ze zbioru. Liczba iteracji jest określona poprzez dzielenie liczby max przez kolejne wielokrotności liczby 10 (oprócz pierwszej iteracji).

Dla cyfr na kolejnych pozycjach (najpierw dla jedności, potem dla dziesiątek, setek itd.) następują wywołania funkcji sortowanieBabelkowe().

Funkcja sortowanieBabelkowe() ma za zadanie sortować zbiór liczb według określonej jako parametr pozycji – pozycja.

Już wiesz

Oto implementacja sortowania bąbelkowego:

Linia 1. static void sortowanieBabelkowe otwórz nawias okrągły int otwórz nawias kwadratowy zamknij nawias kwadratowy tab przecinek int pozycja zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int temp średnik. Linia 4. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny tab kropka length średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. for otwórz nawias okrągły int j znak równości 0 średnik j otwórz nawias ostrokątny tab kropka length minus 1 średnik j plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. if otwórz nawias okrągły otwórz nawias okrągły otwórz nawias okrągły tab otwórz nawias kwadratowy j zamknij nawias kwadratowy prawy ukośnik pozycja zamknij nawias okrągły procent 10 zamknij nawias okrągły zamknij nawias ostrokątny otwórz nawias okrągły otwórz nawias okrągły tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy prawy ukośnik pozycja zamknij nawias okrągły procent 10 zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. temp znak równości tab otwórz nawias kwadratowy j zamknij nawias kwadratowy średnik. Linia 8. tab otwórz nawias kwadratowy j zamknij nawias kwadratowy znak równości tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy średnik. Linia 9. tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości temp średnik. Linia 10. zamknij nawias klamrowy. Linia 11. zamknij nawias klamrowy. Linia 12. zamknij nawias klamrowy. Linia 13. zamknij nawias klamrowy.

Algorytm sortowania bąbelkowego można zoptymalizować poprzez dodanie flagi boolean.

Umieszczenie flagi boolean pozwoli uniknąć niepotrzebnych iteracji. Jeżeli nie wykryje zamiany elementów tablicy po jednej pełnej iteracji, zakończy działanie algorytmu.

Linia 1. static void sortowanieBabelkowe otwórz nawias okrągły int otwórz nawias kwadratowy zamknij nawias kwadratowy tab przecinek int pozycja zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int temp średnik. Linia 3. boolean czyZmiana znak równości false średnik. Linia 5. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny tab kropka length średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. for otwórz nawias okrągły int j znak równości 0 średnik j otwórz nawias ostrokątny tab kropka length minus 1 średnik j plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. if otwórz nawias okrągły otwórz nawias okrągły otwórz nawias okrągły tab otwórz nawias kwadratowy j zamknij nawias kwadratowy prawy ukośnik pozycja zamknij nawias okrągły procent 10 zamknij nawias okrągły zamknij nawias ostrokątny otwórz nawias okrągły otwórz nawias okrągły tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy prawy ukośnik pozycja zamknij nawias okrągły procent 10 zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 8. temp znak równości tab otwórz nawias kwadratowy j zamknij nawias kwadratowy średnik. Linia 9. tab otwórz nawias kwadratowy j zamknij nawias kwadratowy znak równości tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy średnik. Linia 10. tab otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości temp średnik. Linia 12. czyZmiana znak równości true średnik. Linia 13. zamknij nawias klamrowy. Linia 14. zamknij nawias klamrowy. Linia 16. if otwórz nawias okrągły czyZmiana znak równości znak równości false zamknij nawias okrągły otwórz nawias klamrowy. Linia 17. break średnik. Linia 18. zamknij nawias klamrowy. Linia 19. zamknij nawias klamrowy. Linia 20. zamknij nawias klamrowy.

Następnie należy utworzyć dane testowe – zbiór liczb do posortowania oraz wywołać funkcję sortowania pozycyjnego dla zadeklarowanego zbioru:

Linia 1. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int zbior otwórz nawias kwadratowy zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 534 przecinek 123 przecinek 452 przecinek 897 przecinek 342 zamknij nawias klamrowy średnik. Linia 3. sortowaniePozycyjne otwórz nawias okrągły zbior zamknij nawias okrągły średnik. Linia 5. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny zbior kropka length średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. System kropka out kropka print otwórz nawias okrągły zbior otwórz nawias kwadratowy i zamknij nawias kwadratowy plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 7. zamknij nawias klamrowy. Linia 8. zamknij nawias klamrowy.

Ostatnia pętla służy do wypisania posortowanego już zbioru liczb. Wynik sortowania jest poprawny:

Linia 1. 123 342 452 534 897.

Sprawdźmy, czy nasz algorytm sortowania pozycyjnego działa poprawnie – tzn. czy po kolejnych wywołaniach sortowania bąbelkowego zbiór liczb jest sortowany według odpowiednich pozycji. Wypisywanie kolejnych elementów tablicy zostanie dodane w funkcji sortowaniePozycyjne().

Linia 1. static void sortowaniePozycyjne otwórz nawias okrągły int tab otwórz nawias kwadratowy zamknij nawias kwadratowy zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. int max znak równości znajdzMax otwórz nawias okrągły tab zamknij nawias okrągły średnik. Linia 4. for otwórz nawias okrągły int poz znak równości 1 średnik max prawy ukośnik poz zamknij nawias ostrokątny 0 średnik poz asterysk znak równości 10 zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. sortowanieBabelkowe otwórz nawias okrągły tab przecinek poz zamknij nawias okrągły średnik. Linia 7. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny tab kropka length średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 8. System kropka out kropka print otwórz nawias okrągły tab otwórz nawias kwadratowy i zamknij nawias kwadratowy plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 9. zamknij nawias klamrowy. Linia 11. System kropka out kropka println otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 12. zamknij nawias klamrowy. Linia 13. zamknij nawias klamrowy.

Po uruchomieniu programu wypisywane są następujące wyniki:

Linia 1. 452 342 123 534 897. Linia 2. 123 534 342 452 897. Linia 3. 123 342 452 534 897.

Cały kod programu do przetestowania wygląda następująco:

R1G2O9WQupYUe
Wybierz jedno nowe słowo poznane podczas dzisiejszej lekcji i ułóż z nim zdanie.

Słownik

implementacja
implementacja

realizacja algorytmu w konkretnym języku programowania

iteracja
iteracja

technika programowania polegająca na powtarzaniu tej samej operacji określoną liczbę razy lub aż zadany warunek zostanie spełniony

sortowanie bąbelkowe
sortowanie bąbelkowe

(ang. bubble sort) sortowanie polegające na porównywaniu dwóch kolejnych elementów i zamianie ich kolejności, jeżeli zaburza ona porządek, w jakim się sortuje tablicę; sortowanie kończy się, gdy podczas kolejnego przejścia nie dokonano żadnej zmiany

sortowanie stabilne
sortowanie stabilne

cecha algorytmów sortowania, która oznacza, że elementy o równej wartości po posortowaniu będą ułożone w takiej samej kolejności, w jakiej były w nieposortowanym zbiorze