Przeczytaj
Początki sortowania pozycyjnego sięgają XIX wieku. W roku 1890 do opracowania spisu ludności Stanów Zjednoczonych po raz pierwszy zastosowano maszynę licząco‑analityczną. Jej prototyp został zbudowany w 1887 roku przez amerykańskiego inżyniera i wynalazcę Hermana Holleritha.
Idea algorytmu sortowania pozycyjnego
W wypadku sortowania pozycyjnego nie porównuje się ze sobą wprost całych liczb zapisanych w tablicy wejściowej. Elementy są porządkowane ze względu na cyfry umieszczone na tych samych pozycjach.
Proces sortowania rozpoczynamy od najmniej znaczących cyfr jedności i kontynuujemy do chwili, w której posortujemy liczby kolejno według wszystkich cyfr, kończąc na tej najbardziej znaczącej (kolejno: jedności, dziesiątki, setki itd.). Do posortowania liczb według cyfr na danej pozycji możemy użyć dowolnego stabilnego algorytmu sortowaniastabilnego algorytmu sortowania.
Niech A = {140, 12, 68, 9, 512, 24, 60} będzie tablicą wejściową. Uporządkujmy jej elementy, wykorzystując algorytm sortowania pozycyjnego.
Na początek rozważamy cyfry jedności. Sortujemy więc liczby za pomocą dowolnego algorytmu stabilnego tak, aby były ustawione niemalejąco według ostatniej cyfry. Wynikiem pierwszego kroku będzie poniższa tablica.
Indeks: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Liczba: | 140 | 60 | 12 | 512 | 24 | 68 | 9 |
W kolejnym kroku ponownie stabilnie sortujemy tablicę, tym razem według cyfr dziesiątek.
Indeks: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Liczba: | 9 | 12 | 512 | 24 | 140 | 60 | 68 |
Podczas ostatniej iteracji będziemy rozważać cyfry setek.
Indeks: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Liczba: | 9 | 12 | 24 | 60 | 68 | 140 | 512 |
Ostatecznie tablica wynikowa zawierająca liczby posortowane niemalejąco przedstawia się następująco:
AIndeks dolny 11= {9, 12, 24, 60, 68, 140, 512}
Pseudokod
Poniżej została przedstawiona funkcja w pseudokodzie realizująca sortowanie pozycyjne. Wynikiem jej działania jest uporządkowana niemalejąco tablica wartości. Funkcja przyjmuje dwa argumenty: tablicaSortowana
- czyli tablica do posortowania oraz liczbaCyfr
- czyli wartość wskazująca, ile cyfr posiada największa liczba w tablicy.
Sortowanie według i
-tej pozycji oznacza, że dla i
równego liczbaCyfr‑1
bierzemy cyfrę jedności, dla i
równego liczbaCyfr‑2
cyfrę dziesiątek - i tak dalej, aż do i
równego 0
, gdzie bierzemy najbardziej znaczącą cyfrę w liczbie. Dla liczb, które nie posiadają cyfry na danej pozycji, przyjmujemy, że znajduje się tam cyfra 0.
Algorytm sortowania pozycyjnego z wykorzystaniem sortowania kubełkowego
Algorytm sortowania kubełkowego został dokładnie omówiony w e‑materiale Sortowanie kubełkoweSortowanie kubełkowe.
Proces sortowania można wyobrazić sobie jako umieszczanie elementów zbioru w kubełkach, które odpowiadają cyfrom systemu liczbowegosystemu liczbowego. W przypadku systemu dwójkowego do dyspozycji mamy dwa kubełki oznaczone jako 0 i 1; dla systemu dziesiętnego jest ich dziesięć – oznaczają one cyfry od 0 do 9.
Porządkowanie zaczyna się od sprawdzenia cyfr jedności. Liczby zakończone cyfrą 0 trafiają do kubełka oznaczonego symbolem 0, te zakończone cyfrą 1 – do kubełka z numerem 1, a kończące się cyfrą 2 – do kubełka oznaczonego jako 2 itd.
Po ułożeniu wszystkich elementów w pojemnikach wyjmujemy liczby z kubełków. Zaczynamy od kontenera oznaczonego symbolem 0, następnie przechodzimy do kubełka z numerem 1, później 2 - i tak do końca. Liczby opuszczają pojemniki w takiej kolejności, w jakiej zostały do nich włożone.
Wyjmowane kolejno elementy umieszczamy w nowym zbiorze i powtarzamy dla niego opisane czynności. Tym razem sprawdzamy cyfry o wagach większych o 1. Wagą pozycji są kolejne potęgi podstawy systemu liczbowego, w jakim liczba jest zapisana. Elementy znowu trafiają do kubełków, a później jeszcze raz są z nich wyjmowane i tworzą następny zbiór.
Postępujemy tak do momentu, gdy posortujemy liczby według cyfr odpowiadających największym wagom.
Niech A = {833, 997, 268, 69, 100, 584, 321, 333, 512, 660} będzie tablicą wejściową. Uporządkujemy jej elementy, wykorzystując algorytm sortowania pozycyjnego i algorytm sortowania kubełkowego.
Podczas sortowania posłużymy się systemem dziesiętnym. Potrzebnych jest nam zatem 10 kubełków dla cyfr od 0 do 9. Porządkowanie zaczynamy od cyfr jedności (o wagach 10Indeks górny 00):
Kubełek: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
Zawartość: | 660 | 321 | 512 | 333 | 584 | 997 | 268 | 69 |
Potem zapisujemy liczby znajdujące się w kubełkach ponumerowanych od 0 do 9. Pamiętajmy przy tym, aby elementy opuszczały kubełki w takiej kolejności, w jakiej były w nich umieszczane. W rezultacie otrzymujemy następujący zbiór:
AIndeks dolny 11= {100, 660, 321, 512, 833, 333, 584, 997, 268, 69}
Następnie powtarzamy opisane czynności – tym razem bierzemy pod uwagę cyfry dziesiątek (o wagach 10Indeks górny 11):
Kubełek: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
Zawartość: | 100 | 512 | 321 | 333 | 69 | 584 | 997 |
Ponownie zapisujemy liczby z poszczególnych kubełków:
AIndeks dolny 22= {100, 512, 321, 833, 333, 660, 268, 69, 584, 997}
Wszystkie liczby w przykładowym zbiorze są najwyżej trzycyfrowe. Pozostał więc jeszcze jeden cykl operacji. Zauważmy, że wśród elementów znajduje się liczba dwucyfrowa – w jej przypadku brakującą pozycję (odpowiadającą wadze 10Indeks górny 22) zastępujemy cyfrą 0.
Kubełek: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
Zawartość: | 069 | 100 | 268 | 333 | 584 | 660 | 833 | 997 |
Po raz ostatni odczytujemy elementy zapisane w kontenerach. Otrzymana tablica wynikowa jest posortowana rosnąco:
AIndeks dolny 33= {69, 100, 268, 321, 333, 512, 584, 660, 833, 997}
Zapis w pseudokodzie
Zapoznajmy się teraz z implementacją algorytmu zapisaną w postaci pseudokodu.
Specyfikacja:
Dane:
liczbaElementow
– liczba naturalna; długość tablicy z danymiliczbaCyfr
– liczba naturalna; liczba cyfr tworzących największą liczbę z tablicytablica[0..liczbaElementow‑1][0..liczbaCyfr‑1]
– dwuwymiarowa tablica liczb naturalnych; dane do posortowania
Wynik:
tablica[0..liczbaElementow‑1][0..liczbaCyfr‑1]
– posortowana niemalejąco tablica liczb naturalnych
W tym zadaniu występuje nietypowa forma przechowywania liczb. Przykładowo do tablica[4][3] = {{0,5,0}, {1,0,0}, {1,5,6}, {2,0,0}}
możemy odwołać się na dwa różne sposoby. Możemy wskazać albo jedną kompletną tablicę z liczbą, albo pojedynczą cyfrę dowolnej liczby. Dla przykładu {1,5,6}
oznacza liczbę 156.
Przykłady:tablica[0] = {0, 5, 0}
tablica[0][0] = 0
tablica[0][1] = 5
tablica[0][2] = 0
tablica[2] = {1, 5, 6}
tablica[2][0] = 1
tablica[2][1] = 5
tablica[2][2] = 6
Tablica kubełki[0..9]
służy do tymczasowego zapamiętania liczb znajdujących się w kubełku odpowiadającym sprawdzanej obecnie cyfrze.
Ogólny algorytm sortowania pozycyjnego możemy przedstawić w następujący sposób:
Własności sortowania pozycyjnego
Złożoność obliczeniowa zaprezentowanego algorytmu zależy w dużym stopniu od tego, z ilu cyfr składają się liczby zapisane w sortowanej tablicy.
Warto pamiętać, że używając algorytmu sortowania pozycyjnego, nie musimy zapisywać liczb w systemie dziesiętnym. Zwiększenie podstawy systemu liczbowego przekłada się na przyspieszenie działania programu. Zwiększa się też rozmiar wykorzystywanej pamięci.
Algorytm sortowania pozycyjnego jest algorytmem stabilnym, co oznacza, że elementy o równej wartości po posortowaniu będą pojawiać się w takiej samej kolejności jak w nieposortowanym zbiorze.
W przypadku sortowania pozycyjnego wykonuje się tyle cykli operacji, ile cyfr użyto do zapisania największej liczby w sortowanym zbiorze (przyjmijmy, że liczbę cyfr oznaczymy jako d). Całkowita złożoność czasowa będzie zależeć od użytego dodatkowego algorytmu sortowania (oznaczmy złożoność dodatkowego algorytmu jako m). Złożoność czasowa wynosi więc O(dm).
W przypadku użycia sortowania kubełkowego, w każdym przebiegu sprawdzane są wszystkie elementy tablicy (o rozmiarze n), a następnie pobierana jest zawartość każdego z k kubełków. Złożoność obliczeniowa algorytmu wynosi zatem O(d(n + k)).
Zwiększenie liczby kubełków skutkuje zmniejszeniem liczby potrzebnych cyfr (im większa jest wartość k, tym mniejsze jest d). W rezultacie skraca się czas potrzebny do zrealizowania algorytmu.
Zastosowanie sortowania pozycyjnego
Sortownie pozycyjne rzadko wykorzystywane jest w praktyce. Dobrze się sprawdza, gdy należy uporządkować zbiór liczb całkowitych podobnych do siebie (mających np. taką samą liczbę cyfr bądź rozpoczynających się od identycznych ciągów cyfr) albo należących do niewielkiego przedziału. Metoda ta jest z kolei trudna do zastosowania w przypadku porządkowania liczb zmiennoprzecinkowychliczb zmiennoprzecinkowych.
Po zmodyfikowaniu algorytm sortowania pozycyjnego może być z powodzeniem stosowany do znajdowania duplikatów w tablicy.
Słownik
reprezentacja liczby rzeczywistej zapisanej w postaci wykładniczej
mechanizm sortowania, w przypadku którego elementy o identycznych wartościach są umieszczane w uporządkowanym zbiorze w takiej samej kolejności, w jakiej znajdowały się przed sortowaniem
zbiór reguł dotyczących zapisu liczb z wykorzystaniem kombinacji rozmaitych symboli; wyróżniamy systemy liczbowe addytywne (np. rzymski) i pozycyjne (np. dziesiętny)