Sortowanie Przez Mapowanie to uogólnienie sortowania Kubełkowego w połączeniu z Sortowaniem Przez Wstawianie. W ten sposób dane mogą zostać posortowane w czasie zbliżonym do liniowego. Jednak takie sortowanie wymaga dodatkowej pamięci.
Przed przystąpieniem do sortowania należy zastanowić się jak będzie odbywał się przydział do odpowiedniego kosza. Może to wymagać dodatkowej analizy tablicy. Po opracowaniu odpowiedniej strategii należy utworzyć odpowiednią ilość koszy. Każdy kolejny element należy dołączyć do odpowiedniego kosza, ale musi on zostać wstawiony tak, aby elementy w koszu były posortowane. Na koniec wystarczy do tablicy przepisać zawartość z każdego kosza po kolei, aby uzyskać posortowane dane.
Prześledźmy sortowanie listy liczb rzeczywistych L:={1.1, 2.3, 1.8, 1.4, 4.6, 4.4, 1.7}. Na początek należy określić strategię według której dane zostaną wrzucane do koszy. W tym przypadku lista zostanie najpierw przeanalizowana tak, aby znaleźć element maksymalny i minimalny. W celu wyliczenia numera kosza przyporządkowania danego elementu zostanie on pomniejszony o minimum, a potem zostanie usunięta część dziesiętna. Wtedy liczba koszy wyniesie tyle co różnica maksimum zaokrąglonego w górę oraz minimum zaokrąglonego w dół powiększone o 1.
W tym przypadku min = 1.1, a max = 4.6, więc łączna liczba koszy wyniesie = 5 - 1 + 1 = 5. Oznacza to, że do kosza o indeksie 0 trafią wszystkie liczby postaci 1.xx.
Element | Przydział | Kosz 0 | Kosz 1 | Kosz 2 | Kosz 3 | Kosz 4 |
---|---|---|---|---|---|---|
1.1 | int(1.1 - 1) = 0 | {1.1} | {} | {} | {} | {} |
2.3 | int(2.3 - 1) = 1 | {1.1} | {2.3} | {} | {} | {} |
1.8 | int(1.8 - 1) = 0 | {1.1, 1.8} | {2.3} | {} | {} | {} |
1.4 | int(1.4 - 1) = 0 | {1.1, 1.4, 1.8} | {2.3} | {} | {} | {} |
4.6 | int(4.6 - 1) = 3 | {1.1, 1.4, 1.8} | {2.3} | {} | {4.6} | {} |
4.4 | int(4.4 - 1) = 3 | {1.1, 1.4, 1.8} | {2.3} | {} | {4.4, 4.6} | {} |
3.7 | int(3.7 - 1) = 2 | {1.1, 1.4, 1.8} | {2.3} | {3.7} | {4.4, 4.6} | {} |
Na koniec pozostaje scalić wszystkie elementy umieszczone w koszach, aby uzyskać posortowaną listę L':={1.1, 1.4, 1.8, 2.3, 3.7, 4.4, 4.6}.
Najlepsza możliwa złożoność czasowa jest liniowa O(n). Jest to również średnia złożoność algorytmu pod warunkiem, że dane będą dzielone w miarę równo pomiędzy kubełki. Najgorszy możliwy przypadek jest wtedy, gdy wszystkie elementy trafią do jednego kubełka. Wtedy złożoność algorytmu wzrasta do kwadratowej O(n2). Złożoność pamięciowa w każdym przypadku jest zawsze liniowa O(n).
Napisz funkcję sortuj(), która posortuje listę liczb rzeczywistych, która zostanie wprowadzona przez użytkownika. Program powinien wypisać posortowaną listę liczb na ekran.
W przykładowym rozwiązaniu zadania zostanie zastosowana strategia, która została opisana w przykładzie sortowania. Funkcja mapuj() akceptuje dwa argumenty: a - wartość do przydzielenia kosza oraz min - minimalna wartość na liście.
Oto przykładowa funkcja sortująca, która posortuje liczby w tablicy dane. Funkcja nic nie zwraca, ponieważ posortowane dane zostają przepisane do przekazanej tablicy.
Na początku (2. - 9.) tablica jest analizowana w celu znalezienia wartości minimalnej oraz maksymalnej. Na tej podstawie (10.) wyliczona zostaje ilość koszy. Kolejny etap polega na (11. - 15.) przygotowaniu pustych koszy. (16. - 22.) Następnie każdy kolejny element zostaje wrzucony do opowiedniego kosza, ale (18. - 21.) na odpowiedniej pozycji. Na koniec (22. - 27.) wszystkie elementy posortowane wewnątrz każdego kosza zostają przepisane do oryginalnej tablicy.
W celu przetestowania działania napisanej funkcji, a także, aby rozwiązać do końca zadanie potrzebny jest poniższy kod. Wczytuje on od użytkownika ile jest elementów n, a następnie wywyołuje sortowanie i wypisuje wynik.
Napisz funkcję, która posortuje malejąco wprowadzoną listę liczb całkowitych zgodnie z porządkiem leksykograficznym.
Przykładowa posortowana tablica liczb L:={1, 7, 31, 4, 65, 42, 2, 53} będzie wyglądać następująco: