Podczas omawiania funkcji sortowania dostępnych w poszczególnych językach programowania skupimy się na dostępnych w nich klasach i funkcjach wbudowanychfunkcja wbudowanafunkcjach wbudowanych, związanych z algorytmami sortowania.

Ważne!

W zależności od języka programowania funkcje sortujące wywoływane są poprzez podanie ich nazwy, np. sort() lub poprzez podanie klasy albo obiektu i nazwy, np. Arrays.sort() lub lista.sort(). W tym drugim przypadku należy posługiwać się terminem metoda, który oznacza składową funkcję klasy. W tym e‑materiale będziemy zachowywać to rozróżnienie.

Biblioteka standardowa C++

Już wiesz

W języku C++, jeżeli chcemy skorzystać z klas lub funkcji zdefiniowanych w jakimś module biblioteki standardowejbiblioteka standardowabiblioteki standardowej, dołączamy do programu odpowiedni plik nagłówkowy (zawierający odpowiednie deklaracje) za pomocą dyrektywyDyrektywadyrektywy #include.

W dotychczas pisanych programach wskazywaliśmy przestrzeń nazw std, która zawiera wszystkie funkcje i stałe dostępne w ramach bibliotek standardowych języka C++. Wskazanie tej przestrzeni nazw umożliwia deklaracja:

Linia 1. using namespace std średnik.

qsort(), cstdlib

Pierwszą funkcją, którą się zajmiemy, będzie funkcja qsort() zawarta w pliku nagłówkowym <cstdlib>. Wspomniany nagłówek można rozwinąć do C Standard Library, co oznacza, że jest to funkcja odziedziczona jeszcze z języka C. Funkcja implementuje algorytm sortowania szybkiego korzystający z metody „dziel i zwyciężaj”. Jest to algorytm niestabilnystabilny algorytm sortowanianiestabilny, czyli nie gwarantuje zachowania początkowej kolejności elementów równych, a więc dla argumentów równych ich porządek jest niezdefiniowany. Służy do porządkowania tablic lub innych kontenerów danychkontener danychkontenerów danych.

Więcej naa temat tego algorytmu znajdziesz w e‑materiale Sortowanie szybkiePpzx1YyemSortowanie szybkie.

Przykład 1

Zacznijmy od programu, którego zadaniem jest posortowanie niemalejące tablicy liczb przy użyciu funkcji qsort().

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 4. using namespace std średnik. Linia 6. int porownaj otwórz nawias okrągły const void asterysk a przecinek const void asterysk b zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. int arg1 znak równości asterysk otwórz nawias okrągły otwórz nawias okrągły const int asterysk zamknij nawias okrągły a zamknij nawias okrągły średnik. Linia 8. int arg2 znak równości asterysk otwórz nawias okrągły otwórz nawias okrągły const int asterysk zamknij nawias okrągły b zamknij nawias okrągły średnik. Linia 10. if otwórz nawias okrągły arg1 otwórz nawias ostrokątny arg2 zamknij nawias okrągły return minus 1 średnik prawy ukośnik prawy ukośnik jeśli a otwórz nawias ostrokątny b. Linia 11. if otwórz nawias okrągły arg1 zamknij nawias ostrokątny arg2 zamknij nawias okrągły return 1 średnik prawy ukośnik prawy ukośnik jeśli a zamknij nawias ostrokątny b. Linia 12. return 0 średnik prawy ukośnik prawy ukośnik jeśli równe. Linia 13. zamknij nawias klamrowy. Linia 15. int main otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 16. const int rozmiar znak równości 6 średnik. Linia 17. int tablica otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 500 przecinek 400 przecinek 425 przecinek minus 500 przecinek 0 przecinek 5 zamknij nawias klamrowy średnik. Linia 19. qsort otwórz nawias okrągły tablica przecinek rozmiar przecinek sizeof asterysk tablica przecinek porownaj zamknij nawias okrągły średnik. Linia 20. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny rozmiar średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 21. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 22. zamknij nawias klamrowy. Linia 23. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. minus 500. Linia 3. 5. Linia 4. 400. Linia 5. 425. Linia 6. 500.

Wywołanie omawianej funkcji w zaprezentowanym programie ma postać qsort(tablica, rozmiar, sizeof tablica, porownaj);.

Kolejne argumenty to:

  • tablica – wskaźnik do pierwszego elementu sortowanej tablicy, czyli nazwa tablicy, która w języku C++ jest takim wskaźnikiem,

  • rozmiar – liczba elementów tablicy,

  • sizeof *tablica – rozmiar w bajtach pojedynczego elementu tablicy zwracany przez operator sizeof,

  • porownaj – funkcja używana do porównywania elementów tablicy.

Funkcja qsort() nie zwraca żadnej wartości i działa bezpośrednio na podanej tablicy, tzn. zmienia kolejność zapisanych w niej elementów. O sposobie sortowania decyduje funkcja porównująca podawana jako czwarty argument( zwana komparatoremkomparatorkomparatorem). Przeanalizujmy jej działanie.

Z jej deklaracji (int porownaj(const void* a, const void* b)) wynika, że przyjmuje ona dwa wskaźniki na wartości nieokreślonego typu. Dlatego pierwszą czynnością wewnątrz funkcji jest ustalenie typu porównywanych wartości. Przykładowa instrukcja *((const int*)a); konwertuje wskaźnik a do niemodyfikowalnego typu całkowitego za pomocą rzutowaniarzutowanie, konwersja typurzutowania. Gdybyśmy porównywali liczby zmiennoprzecinkowe, do rzutowania użylibyśmy instrukcji *((const float*)a);.

Ponieważ parametry funkcji porównującej nie mają określonego typu, może ona porównywać według przyjętych kryteriów nie tylko typy podstawowe, np. liczby całkowite lub zmiennoprzecinkowe, ale również obiektyobiektobiekty.

Omawiana funkcja zwraca wartość całkowitą oznaczającą wynik porównania, przy czym:

  • jeżeli a < b, należy zwrócić wartość mniejszą od 0, np. -1,

  • jeżeli a > b, należy zwrócić wartość większą od 0, np. 1,

  • jeżeli a == b, należy zwrócić wartość 0.

Ćwiczenie 1

Na podstawie przykładu 1 napisz program, który będzie sortował liczby zmiennoprzecinkowe.

W następnym kroku zmodyfikuj funkcję porownaj() w taki sposób, żeby odwrócić porządek sortowania (liczby powinny być sortowane nierosnąco).

RJIiOpNWOWySy
Ciekawostka

Funkcja qsort() jest jedną z wolniejszych funkcji sortujących dostępnych w bibliotece standardowej języka C++. Nowsze funkcje sortujące zapewniają lepsze wyniki z punktu widzenia wydajności.

sort(), algorithm

Kolejna wbudowana funkcja sortująca to sort(). Jej deklaracja znajduje się w nagłówku <algorithm>. Funkcja ta wykorzystuje hybrydowy niestabilny algorytm sortowania o nazwie IntrosortintrosortIntrosort Porządek równych elementów jest nieokreślony.

Przykład 2

Przeanalizujmy przykład, w którym porządkujemy tablicę liczb całkowitych rosnąco.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny algorithm zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny climits zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. int main otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 8. const int rozmiar znak równości 6 średnik. Linia 9. int tablica otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 500 przecinek 400 przecinek 425 przecinek minus 500 przecinek 0 przecinek 5 zamknij nawias klamrowy średnik. Linia 11. sort otwórz nawias okrągły tablica przecinek tablica plus rozmiar zamknij nawias okrągły średnik. Linia 12. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny rozmiar średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 13. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 14. zamknij nawias klamrowy. Linia 15. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. minus 500. Linia 3. 5. Linia 4. 400. Linia 5. 425. Linia 6. 500.

Funkcja sort() w podstawowym wywołaniu porządkuje elementy klasy array lub vector niemalejąco w zakresie wyznaczanym przez pierwszy i drugi argument. Do porównywania elementów domyślnie używany jest operator <. W przypadku porządkowania tablic początek i koniec sortowanego zakresu możemy podać w różny sposób, np.:

  • sort(tablica, tablica + rozmiar) – pierwszy argument jest wskaźnikiem wyznaczającym początek sortowanego zakresu, drugi argument to długość sortowanego zakresu, którą można też rozumieć jako liczbę elementów do posortowania;

  • sort(&tablica[0], &tablica[rozmiar]) – obydwa argumenty są referencjami pierwszego i ostatniego sortowanego elementu podawanymi za pomocą operatora &, przy czym element wskazywany przez koniec zakresu nie jest porządkowany.

Z tego wynika, że gdybyśmy chcieli porządkować tablicę np. bez pierwszego i ostatniego elementu, możemy użyć wywołań: sort(tablica + 1, tablica + rozmiar) lub sort(&tablica[1], &tablica[rozmiar‑1]).

Jeżeli chcemy używać innego sposobu porządkowania niż domyślny lub chcemy porządkować złożone struktury lub obiekty (instancje klas użytkownika), możemy użyć własnej funkcji porównującej podawanej jako trzeci argument. Funkcja przyjmuje dwa argumenty i zwraca wartość typu bool:

  • true (prawda) – jeżeli pierwszy element jest mniejszy od drugiego,

  • false (fałsz) – jeżeli pierwszy element jest większy od drugiego.

Przykład 3

Zapoznajmy się z przykładem, w którym dzielimy tablicę liczb na dwie tablice – liczb parzystych i nieparzystych, a następnie sortujemy je rosnąco.

By to zrobić, sprawdzamy podzielność liczb przez 2.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny cstdlib zamknij nawias ostrokątny. Linia 4. using namespace std średnik. Linia 6. int porownaj otwórz nawias okrągły const void asterysk a przecinek const void asterysk b zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. int arg1 znak równości asterysk otwórz nawias okrągły otwórz nawias okrągły const int asterysk zamknij nawias okrągły a zamknij nawias okrągły średnik. Linia 8. int arg2 znak równości asterysk otwórz nawias okrągły otwórz nawias okrągły const int asterysk zamknij nawias okrągły b zamknij nawias okrągły średnik. Linia 10. if otwórz nawias okrągły arg1 otwórz nawias ostrokątny arg2 zamknij nawias okrągły return minus 1 średnik. Linia 11. if otwórz nawias okrągły arg1 zamknij nawias ostrokątny arg2 zamknij nawias okrągły return 1 średnik. Linia 13. return 0 średnik. Linia 14. zamknij nawias klamrowy. Linia 16. int main otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 17. const int rozmiar znak równości 6 średnik. Linia 18. int tablica otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy znak równości otwórz nawias klamrowy 500 przecinek 400 przecinek 425 przecinek minus 500 przecinek 0 przecinek 5 zamknij nawias klamrowy średnik. Linia 21. int tab podkreślnik parzyste otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy średnik. Linia 22. int tab podkreślnik nieparzyste otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy średnik. Linia 24. int l znak równości 0 przecinek k znak równości 0 średnik. Linia 26. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny rozmiar średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 27. if otwórz nawias okrągły tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy procent 2 znak równości znak równości 0 zamknij nawias okrągły otwórz nawias klamrowy. Linia 28. tab podkreślnik parzyste otwórz nawias kwadratowy l zamknij nawias kwadratowy znak równości tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 29. l plus plus średnik. Linia 30. zamknij nawias klamrowy. Linia 31. else otwórz nawias klamrowy. Linia 32. tab podkreślnik nieparzyste otwórz nawias kwadratowy k zamknij nawias kwadratowy znak równości tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy średnik. Linia 33. k plus plus średnik. Linia 34. zamknij nawias klamrowy. Linia 35. zamknij nawias klamrowy. Linia 37. qsort otwórz nawias okrągły tab podkreślnik parzyste przecinek l przecinek sizeof asterysk tab podkreślnik parzyste przecinek porownaj zamknij nawias okrągły średnik. Linia 39. qsort otwórz nawias okrągły tab podkreślnik nieparzyste przecinek k przecinek sizeof asterysk tab podkreślnik nieparzyste przecinek porownaj zamknij nawias okrągły średnik. Linia 41. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny k średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 42. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tab podkreślnik nieparzyste otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów cudzysłów średnik. Linia 43. zamknij nawias klamrowy. Linia 44. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny l średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 45. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tab podkreślnik parzyste otwórz nawias kwadratowy i zamknij nawias kwadratowy otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów cudzysłów średnik. Linia 46. zamknij nawias klamrowy. Linia 48. cout otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 50. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. 5 425 minus 500 0 400 500.

Funkcja przyjmuje dwa wskaźniki const void*, oznaczające dwa elementy tablicy do porównania. Ponieważ funkcja qsort operuje na tablicach pamięci o nieokreślonym typie, parametry funkcji są przekazywane jako wskaźniki na typ void, co pozwala na elastyczne użycie funkcji do różnych typów danych.

Wewnątrz funkcji porownaj wskaźniki są rzutowane na wskaźniki do typu int, ponieważ tablica zawiera elementy typu int. Operacja ta umożliwia dostęp do wartości przechowywanych w tych elementach.

Wartości, do których wskazują wskaźniki, są porównywane. Jeśli pierwsza wartość jest mniejsza niż druga, funkcja zwraca wartość -1. Jeśli pierwsza wartość jest większa niż druga, zwracana jest wartość 1. Jeśli obie wartości są równe, funkcja zwraca 0.

Funkcja zwraca wartość określającą porządek między elementami. Wartości zwracane są wykorzystywane przez funkcję sortującą qsort, aby odpowiednio ustawić elementy tablicy.

Ćwiczenie 2

W kodzie ostatniego przykładu zmień funkcję porownaj() w taki sposób, żeby odwrócić porządek sortowania, tzn. na początku powinny zostać wypisane uporządkowane niemalejąco liczby parzyste, a po nich również uporządkowane niemalejąco liczby nieparzyste.

RgerELFqt7Rao
t

stable_sort(), algorithm

Jeżeli zależy nam na sortowaniu stabilnymstabilny algorytm sortowaniastabilnym, np. kiedy porządkujemy złożone struktury lub obiekty, powinniśmy używać funkcji stable_sort(), która do porządkowania wykorzystuje algorytm sortowania przez scalanie.

Więcej na temat tego algorytmu znajdziesz w e‑materiale Sortowanie przez scalaniePNHdnGJ4ISortowanie przez scalanie.

Przykład 4

Oto przykład sortowania struktur zawierających imię i ocenę ucznia, które chcemy uporządkować nierosnąco według ocen, ale przy zachowaniu wejściowego porządku imion uczniów.

Linia 1. kratka include otwórz nawias ostrokątny iostream zamknij nawias ostrokątny. Linia 2. kratka include otwórz nawias ostrokątny string zamknij nawias ostrokątny. Linia 3. kratka include otwórz nawias ostrokątny algorithm zamknij nawias ostrokątny. Linia 5. using namespace std średnik. Linia 7. struct uczen otwórz nawias klamrowy. Linia 8. string imie średnik. Linia 9. int ocena średnik. Linia 10. zamknij nawias klamrowy średnik. Linia 12. bool porownaj otwórz nawias okrągły uczen u1 przecinek uczen u2 zamknij nawias okrągły otwórz nawias klamrowy. Linia 13. return u1 kropka ocena zamknij nawias ostrokątny u2 kropka ocena średnik. Linia 14. zamknij nawias klamrowy. Linia 16. int main otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 17. const int rozmiar znak równości 5 średnik. Linia 18. uczen tablica otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy znak równości otwórz nawias klamrowy otwórz nawias klamrowy cudzysłów Adam cudzysłów przecinek 3 zamknij nawias klamrowy przecinek otwórz nawias klamrowy cudzysłów Ewa cudzysłów przecinek 5 zamknij nawias klamrowy przecinek otwórz nawias klamrowy cudzysłów Anna cudzysłów przecinek 3 zamknij nawias klamrowy przecinek otwórz nawias klamrowy cudzysłów Olga cudzysłów przecinek 5 zamknij nawias klamrowy przecinek otwórz nawias klamrowy cudzysłów Jacek cudzysłów przecinek 3 zamknij nawias klamrowy zamknij nawias klamrowy średnik. Linia 20. stable podkreślnik sort otwórz nawias okrągły tablica przecinek ampersant tablica otwórz nawias kwadratowy rozmiar zamknij nawias kwadratowy przecinek porownaj zamknij nawias okrągły średnik. Linia 21. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny rozmiar średnik i plus plus zamknij nawias okrągły otwórz nawias klamrowy. Linia 22. cout otwórz nawias ostrokątny otwórz nawias ostrokątny tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy kropka imie otwórz nawias ostrokątny otwórz nawias ostrokątny cudzysłów cudzysłów otwórz nawias ostrokątny otwórz nawias ostrokątny tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy kropka ocena otwórz nawias ostrokątny otwórz nawias ostrokątny endl średnik. Linia 23. zamknij nawias klamrowy. Linia 24. zamknij nawias klamrowy.

Funkcja porównująca porownaj() jako argumenty otrzymuje dwie struktury zawierające imię i ocenę ucznia. Funkcja zwraca wartość true, jeżeli ocena pierwszego ucznia jest większa od oceny drugiego. W ten sposób otrzymamy uporządkowanie nierosnące według ocen. Funkcja stable_sort() gwarantuje zachowanie stabilności tego sortowania.

Wynik działania programu:

Linia 1. Ewa 5. Linia 2. Olga 5. Linia 3. Adam 3. Linia 4. Anna 3. Linia 5. Jacek 3.

Warto zwrócić uwagę, że porządek wejściowy uczniów o takich samych ocenach został zachowany.

Klasy i metody w języku Java

Arrays.sort()

W przypadku języka Java wbudowane metody sortujące znajdziemy w klasie Arrays z pakietu pakietu java.util.Arrays. Jedną z nich jest metoda sort().

Jak wynika z dokumentacji języka Java, metoda sort() korzysta z różnych algorytmów sortowania w zależności od typu danych, które są sortowane. Najczęściej typy prostetyp prostytypy proste sortowane są przy użyciu odmiany algorytmu sortowania szybkiego o nazwie Dual‑Pivot Quicksort. Jest to sortowanie niestabilne. W przypadku sortowania typów złożonych, czyli obiektów, wykorzystywany jest stabilny hybrydowy algorytm o nazwie TimsortTimsortTimsort.

Przykład 5

Spójrzmy na przykład programu, który porządkuje liczby całkowite niemalejąco przy użyciu metody sort():

Linia 1. import java kropka util kropka Arrays średnik. Linia 3. public class Przyklad1 otwórz nawias klamrowy. Linia 5. 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 6. int otwórz nawias kwadratowy zamknij nawias kwadratowy tablica1 znak równości otwórz nawias klamrowy 500 przecinek 400 przecinek 425 przecinek minus 500 przecinek 0 przecinek 5 zamknij nawias klamrowy średnik. Linia 7. Arrays kropka sort otwórz nawias okrągły tablica1 zamknij nawias okrągły średnik. Linia 9. int otwórz nawias kwadratowy zamknij nawias kwadratowy tablica2 znak równości otwórz nawias klamrowy 500 przecinek 400 przecinek 425 przecinek minus 500 przecinek 0 przecinek 5 zamknij nawias klamrowy średnik. Linia 10. Arrays kropka sort otwórz nawias okrągły tablica2 przecinek 1 przecinek 5 zamknij nawias okrągły średnik. Linia 12. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica1 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 13. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica2 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 14. zamknij nawias klamrowy. Linia 15. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy minus 500 przecinek 0 przecinek 5 przecinek 400 przecinek 425 przecinek 500 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy 500 przecinek minus 500 przecinek 0 przecinek 400 przecinek 425 przecinek 5 zamknij nawias kwadratowy.

Wyjaśnijmy działanie zaprezentowanego programu. Język Java dopuszcza przeciążanie metodprzeciążanie metodprzeciążanie metod, dlatego możemy używać dwóch wywołań metody sortującej:

  1. Arrays.sort(tablica1) – pozwala porządkować wszystkie elementy podanej jako argument tablicy niemalejąco,

  2. Arrays.sort(tablica2, 1, 5) – umożliwia porządkowanie niemalejące zakresu elementów wyznaczonych przez podane indeksy, przy czym element wskazywany przez indeks końcowy nie jest brany pod uwagę.

Do zamiany liczb zawartych w tablicy na ciąg znaków używamy metody toString() klasy Arrays.

Ćwiczenie 3
R1eTakihlbWkp

Omawiana funkcja sort() domyślnie porządkuje podane elementy niemalejąco. Gdy chcemy zmienić porządek sortowania, musimy podać jeszcze jeden argument, czyli komparator odpowiedzialny za porównywanie poszczególnych wartości w sortowanej tablicy.

Przykład 6

Oto przykład porządkowania liczb nierosnąco przy użyciu komparatora reverseOrder() z klasy Collections:

Linia 1. import java kropka util kropka Arrays średnik. Linia 2. import java kropka util kropka Collections średnik. Linia 3. import java kropka lang kropka Integer średnik. Linia 5. public class Przyklad2 otwórz nawias klamrowy. Linia 6. 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 7. Integer otwórz nawias kwadratowy zamknij nawias kwadratowy tablica1 znak równości otwórz nawias klamrowy 5 przecinek 0 przecinek 500 przecinek 400 przecinek minus 500 przecinek 425 zamknij nawias klamrowy średnik. Linia 8. Integer otwórz nawias kwadratowy zamknij nawias kwadratowy tablica2 znak równości otwórz nawias klamrowy 5 przecinek 0 przecinek 500 przecinek 400 przecinek minus 500 przecinek 425 zamknij nawias klamrowy średnik. Linia 10. Arrays kropka sort otwórz nawias okrągły tablica1 przecinek Collections kropka reverseOrder otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 11. Arrays kropka sort otwórz nawias okrągły tablica2 przecinek 1 przecinek 5 przecinek Collections kropka reverseOrder otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 13. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica1 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 14. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica2 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 15. zamknij nawias klamrowy. Linia 16. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy 500 przecinek 425 przecinek 400 przecinek 5 przecinek 0 przecinek minus 500 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy 5 przecinek 500 przecinek 400 przecinek 0 przecinek minus 500 przecinek 425 zamknij nawias kwadratowy.
Ważne!

Kiedy używamy metody sort() z komparatorem, elementy tablicy nie mogą być typami prostymi, dlatego w zaprezentowanym programie elementy tablicy są instancjami klasy Integer przeznaczonej do obsługi liczb całkowitych.

Dla zainteresowanych

Jeśli chcemy, możemy też napisać swój komparator, co wymaga zaimplementowania interfejsu Comparator. Poniżej przykład użycia własnego komparatora w metodzie Arrays.sort() do porządkowania tablicy zawierającej elementy w postaci obiektów reprezentujących uczniów opisanych przez imię i wiek. Obiekty porządkowane są niemalejąco według wieku uczniów.

Przykład 7
Linia 1. import java kropka util kropka Arrays średnik. Linia 2. import java kropka util kropka Collections średnik. Linia 3. import java kropka util kropka Comparator średnik. Linia 5. class Uczen otwórz nawias klamrowy. Linia 6. String imie średnik. Linia 7. int wiek średnik. Linia 8. public Uczen otwórz nawias okrągły String imie przecinek int wiek zamknij nawias okrągły otwórz nawias klamrowy. Linia 9. this kropka imie znak równości imie średnik. Linia 10. this kropka wiek znak równości wiek średnik. Linia 11. zamknij nawias klamrowy. Linia 12. public String toString otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 13. return this kropka imie plus cudzysłów cudzysłów plus this kropka wiek średnik. Linia 14. zamknij nawias klamrowy. Linia 15. zamknij nawias klamrowy. Linia 17. class Porownaj implements Comparator otwórz nawias ostrokątny Uczen zamknij nawias ostrokątny otwórz nawias klamrowy. Linia 18. public int compare otwórz nawias okrągły Uczen u1 przecinek Uczen u2 zamknij nawias okrągły otwórz nawias klamrowy. Linia 19. return u1 kropka wiek minus u2 kropka wiek średnik. Linia 20. zamknij nawias klamrowy. Linia 21. zamknij nawias klamrowy. Linia 23. public class Przyklad3 otwórz nawias klamrowy. Linia 24. 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 25. Uczen otwórz nawias kwadratowy zamknij nawias kwadratowy tablica znak równości otwórz nawias klamrowy. Linia 26. new Uczen otwórz nawias okrągły cudzysłów Adam cudzysłów przecinek 16 zamknij nawias okrągły przecinek. Linia 27. new Uczen otwórz nawias okrągły cudzysłów Ewa cudzysłów przecinek 18 zamknij nawias okrągły przecinek. Linia 28. new Uczen otwórz nawias okrągły cudzysłów Anna cudzysłów przecinek 19 zamknij nawias okrągły przecinek. Linia 29. new Uczen otwórz nawias okrągły cudzysłów Anna cudzysłów przecinek 17 zamknij nawias okrągły przecinek. Linia 30. new Uczen otwórz nawias okrągły cudzysłów Piotr cudzysłów przecinek 16 zamknij nawias okrągły. Linia 31. zamknij nawias klamrowy średnik. Linia 33. Arrays kropka sort otwórz nawias okrągły tablica przecinek new Porownaj otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 35. for otwórz nawias okrągły int i znak równości 0 średnik i otwórz nawias ostrokątny tablica kropka length średnik i plus plus zamknij nawias okrągły. Linia 36. System kropka out kropka println otwórz nawias okrągły tablica otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły średnik. Linia 38. zamknij nawias klamrowy. Linia 39. zamknij nawias klamrowy.

Porządkowanymi elementami są obiekty będące instancjami klasy Uczen, która definiuje dwa atrybuty: imie oraz wiek, a także metodę toString(), którą wykorzystujemy do wypisania informacji o obiekcie w postaci ciągu znaków.

W wywołaniu komparator jest instancją klasy Porownaj. Klasa ta implementuje interfejs Comparator i nadpisuje metodę compare, która zwraca wartość całkowitą, w tym przypadku różnicę między wiekiem uczniów. Wartość mniejsza od 0 oznacza, że uczeń u1 jest młodszy od ucznia u2, wartość większa od 0 to sytuacja odwrotna, natomiast 0 oznacza, że wiek uczniów jest taki sam.

Po uruchomieniu powyższego programu zobaczymy listę uczniów posortowaną stabilnie według ich wieku w sposób nierosnący.

Wynik działania programu:

Linia 1. Adam 16. Linia 2. Piotr 16. Linia 3. Anna 17. Linia 4. Ewa 18. Linia 5. Anna 19.
Ćwiczenie 4

Zmień komparator w taki sposób, żeby odwrócić porządek sortowania, tzn. żeby uczniowie zostali uporządkowani nierosnąco według wieku.

RHonlGRPwi9co
Ciekawostka

Funkcja sort() dostępna jest również w klasie Collections i działa podobnie jak Array.sort(), ale ma szersze zastosowanie, tj. służy do sortowania nie tylko tablic, ale głównie list obiektów.

parallelSort()

W klasie Arrays zaimplementowana jest również metoda o nazwie parallelSort(), która wykorzystuje algorytm sortowania przez scalanie. Metoda ta może korzystać z wielu wątków jednocześnie, więc dla większych zbiorów danych jest zauważalnie szybsza. Przyjmuje ona identyczne argumenty jak funkcja sort(), w tej samej kolejności.

Przykład 8

Przykład sortowania tablic liczb całkowitych przy użyciu metody parallelSort() i komparatora reverseOrder().

Linia 1. import java kropka util kropka Arrays średnik. Linia 2. import java kropka util kropka Collections średnik. Linia 3. import java kropka util kropka Comparator średnik. Linia 4. import java kropka lang kropka Integer średnik. Linia 6. public class Przyklad4 otwórz nawias klamrowy. Linia 7. 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 8. int otwórz nawias kwadratowy zamknij nawias kwadratowy tablica1 znak równości otwórz nawias klamrowy 400 przecinek minus 65 przecinek 23 przecinek 0 przecinek minus 234 przecinek 112 przecinek 345 zamknij nawias klamrowy średnik. Linia 9. Integer otwórz nawias kwadratowy zamknij nawias kwadratowy tablica2 znak równości otwórz nawias klamrowy 400 przecinek minus 65 przecinek 23 przecinek 0 przecinek minus 234 przecinek 112 przecinek 345 zamknij nawias klamrowy średnik. Linia 11. Arrays kropka parallelSort otwórz nawias okrągły tablica1 zamknij nawias okrągły średnik. Linia 12. Arrays kropka parallelSort otwórz nawias okrągły tablica2 przecinek 1 przecinek 6 przecinek Collections kropka reverseOrder otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 14. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica1 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 15. System kropka out kropka println otwórz nawias okrągły Arrays kropka toString otwórz nawias okrągły tablica2 zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 16. zamknij nawias klamrowy. Linia 17. zamknij nawias klamrowy.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy minus 234 przecinek minus 65 przecinek 0 przecinek 23 przecinek 112 przecinek 345 przecinek 400 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy 400 przecinek 112 przecinek 23 przecinek 0 przecinek minus 65 przecinek minus 234 przecinek 345 zamknij nawias kwadratowy.

W kodzie zaprezentowanego programu warto zauważyć, że metody parallel_sort() możemy używać do porządkowania zarówno typów złożonych, jak i podstawowych.

Funkcje w języku Python

sorted()

Funkcja sorted() jest częścią biblioteki standardowej języka Python i wykorzystywana jest do porządkowania danych różnych typu. Mogą to być np. listy, krotki, ciągi znaków, słowniki czy zbiory.

Podczas sortowania funkcja korzysta z algorytmu timsorttimsorttimsort, nie modyfikuje sortowanych obiektów, ale zwraca nową posortowaną listę. Zastosowany algorytm gwarantuje stabilność sortowania.

Przykład 9

Oto przykład porządkowania listy liczb. Warto zwrócić uwagę, że w drugim wywołaniu funkcji używamy dodatkowego argumentu reverse.

Linia 1. lista znak równości otwórz nawias kwadratowy 3 kropka 14 przecinek minus 59 przecinek 32 przecinek 0 przecinek minus 500 przecinek 400 przecinek 1 zamknij nawias kwadratowy. Linia 3. print otwórz nawias okrągły sorted otwórz nawias okrągły lista zamknij nawias okrągły zamknij nawias okrągły. Linia 4. print otwórz nawias okrągły sorted otwórz nawias okrągły lista przecinek reverse znak równości True zamknij nawias okrągły zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy minus 500 przecinek minus 59 przecinek 0 przecinek 1 przecinek 3 kropka 14 przecinek 32 przecinek 400 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy 400 przecinek 32 przecinek 3 kropka 14 przecinek 1 przecinek 0 przecinek minus 59 przecinek minus 500 zamknij nawias kwadratowy.
Ćwiczenie 5
RJOGOAIFKq07K
Ćwiczenie 6

Dana jest lista liczb: lista = [5, 8, -3, 1, 10, 3.14, 18]. Podaj ciąg wywołań instrukcji sorted(), który po wykonaniu spowoduje wypisanie następujących komunikatów:

Linia 1. otwórz nawias kwadratowy minus 3 przecinek 1 przecinek 3 kropka 14 przecinek 5 przecinek 8 przecinek 10 przecinek 18 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy 18 przecinek 10 przecinek 8 przecinek 5 przecinek 3 kropka 14 przecinek 1 przecinek minus 3 zamknij nawias kwadratowy. Linia 3. otwórz nawias kwadratowy minus 3 przecinek 1 przecinek 3 kropka 14 przecinek 5 przecinek 8 przecinek 10 przecinek 18 zamknij nawias kwadratowy.
R4alsIc7ohX80

Funkcja sorted() umożliwia określanie własnych kryteriów sortowania za pomocą opcjonalnego argumentu key. Zapoznajmy się z przykładami.

Ważne!

Jeżeli jako argument key, tj. klucz, podamy wartość None lub w ogóle go nie podamy, zastosowane zostanie sortowanie domyślne, tj. niemalejąco.

W poniższym przykładzie będzie to porządkowanie alfabetyczne słów według kodów znaków, dlatego wyrazy pisane wielkimi literami znajdą się na początku zwróconej listy.

Linia 1. print otwórz nawias okrągły sorted otwórz nawias okrągły cudzysłów Przykładowy tekst który chcemy uporządkować cudzysłów kropka split otwórz nawias okrągły zamknij nawias okrągły przecinek key znak równości None zamknij nawias okrągły zamknij nawias okrągły. Linia 2. print otwórz nawias okrągły sorted otwórz nawias okrągły cudzysłów Przykładowy tekst który chcemy uporządkować cudzysłów kropka split otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy apostrof Przykładowy apostrof przecinek apostrof chcemy apostrof przecinek apostrof który apostrof przecinek apostrof tekst apostrof przecinek apostrof uporządkować apostrof zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy apostrof Przykładowy apostrof przecinek apostrof chcemy apostrof przecinek apostrof który apostrof przecinek apostrof tekst apostrof przecinek apostrof uporządkować apostrof zamknij nawias kwadratowy.
Przykład 10

W poniższym kodzie jako argumentu key używamy funkcji anonimowejfunkcja anonimowafunkcji anonimowej wprowadzanej przez słowo kluczowe lambda. Funkcja wykonywana jest na każdym elemencie listy przekazywanym w argumencie element przed posortowaniem i zwraca klucz, tj.  wartość wykorzystywaną do sortowania.

W tym przypadku jest to wartość True, jeżeli element jest liczbą parzystą, czyli jest większy, lub False w przeciwnym przypadku, czyli gdy jest mniejszy. Dlatego w posortowanej liście liczby nieparzyste będą poprzedzały parzyste.

Linia 1. lista znak równości otwórz nawias kwadratowy 1 przecinek 2 przecinek 3 przecinek 4 przecinek 5 przecinek 6 przecinek 7 przecinek 8 przecinek 9 przecinek 10 zamknij nawias kwadratowy. Linia 3. print otwórz nawias okrągły sorted otwórz nawias okrągły lista przecinek key znak równości lambda element dwukropek element procent 2 znak równości znak równości 0 zamknij nawias okrągły zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy 1 przecinek 3 przecinek 5 przecinek 7 przecinek 9 przecinek 2 przecinek 4 przecinek 6 przecinek 8 przecinek 10 zamknij nawias kwadratowy.
Przykład 11

Zapoznajmy się z przykładem programu, który porządkuje wyrazy zapisane w ciągu znaków niemalejąco pod względem ich długości.

Linia 1. print otwórz nawias okrągły sorted otwórz nawias okrągły cudzysłów Przykładowy tekst który chcemy uporządkować cudzysłów kropka split otwórz nawias okrągły zamknij nawias okrągły przecinek key znak równości len zamknij nawias okrągły zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy apostrof tekst apostrof przecinek apostrof który apostrof przecinek apostrof chcemy apostrof przecinek apostrof Przykładowy apostrof przecinek apostrof uporządkować apostrof zamknij nawias kwadratowy.

Metoda split() dzieli ciąg znaków na podciągi, wykorzystując znaki białe (spacje, tabulatory) i zwraca ich listę. Listę sortujemy, wskazując w argumencie key jako kryterium funkcję len(), która zwraca ich długość.

Ćwiczenie 7

Zmień  wywołania funkcji sorted(), tak aby odwrócić porządek sortowania.

R1Pn8K3Q3H95O

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy 1 przecinek 3 przecinek 5 przecinek 7 przecinek 9 przecinek 2 przecinek 4 przecinek 6 przecinek 8 przecinek 10 zamknij nawias kwadratowy. Linia 2. otwórz nawias kwadratowy apostrof tekst apostrof przecinek apostrof który apostrof przecinek apostrof chcemy apostrof przecinek apostrof Przykładowy apostrof przecinek apostrof uporządkować apostrof zamknij nawias kwadratowy.

Argumentu key często używa się do porządkowania danych składających się z wielu wartości. Jedna z wartości wybrana zostaje jako klucz sortowania. Takie dane zapisane mogą być w różnych strukturach, np. w krotkach lub słownikach, mogą również być atrybutami obiektów będących instancjami klas użytkownika.

Poniżej pokażemy przykłady sortowania danych uczniów składających się z imion i wieku niemalejąco według wieku ucznia.

Przykład 12

Zacznijmy od przykładu, w którym dane uczniów zapisano w krotkach. Listę krotek sortujemy w porządku niemalejącym wg założonego kryterium, tj. według wieku uczniów.

Linia 1. krotki znak równości otwórz nawias kwadratowy. Linia 2. otwórz nawias okrągły apostrof Adam apostrof przecinek 16 zamknij nawias okrągły przecinek. Linia 3. otwórz nawias okrągły apostrof Ewa apostrof przecinek 18 zamknij nawias okrągły przecinek. Linia 4. otwórz nawias okrągły apostrof Anna apostrof przecinek 19 zamknij nawias okrągły przecinek. Linia 5. otwórz nawias okrągły apostrof Anna apostrof przecinek 17 zamknij nawias okrągły przecinek. Linia 6. otwórz nawias okrągły apostrof Piotr apostrof przecinek 16 zamknij nawias okrągły. Linia 7. zamknij nawias kwadratowy. Linia 9. print otwórz nawias okrągły sorted otwórz nawias okrągły krotki przecinek key znak równości lambda uczen dwukropek uczen otwórz nawias kwadratowy 1 zamknij nawias kwadratowy zamknij nawias okrągły zamknij nawias okrągły.

Sortowane krotki przekazywane są do funkcji anonimowej (lambda), która jako klucz zwraca ich drugi element (uczen[1]), tj. wiek ucznia.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy otwórz nawias okrągły apostrof Adam apostrof przecinek 16 zamknij nawias okrągły przecinek otwórz nawias okrągły apostrof Piotr apostrof przecinek 16 zamknij nawias okrągły przecinek otwórz nawias okrągły apostrof Anna apostrof przecinek 17 zamknij nawias okrągły przecinek otwórz nawias okrągły apostrof Ewa apostrof przecinek 18 zamknij nawias okrągły przecinek otwórz nawias okrągły apostrof Anna apostrof przecinek 19 zamknij nawias okrągły zamknij nawias kwadratowy.
Przykład 13

W kolejnym przykładzie imiona i wiek uczniów zapisane są w słownikach. Listę słowników porządkujemy niemalejąco według wieku uczniów.

Linia 1. slowniki znak równości otwórz nawias kwadratowy. Linia 2. otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Adam apostrof przecinek apostrof wiek apostrof dwukropek 16 zamknij nawias klamrowy przecinek. Linia 3. otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Ewa apostrof przecinek apostrof wiek apostrof dwukropek 18 zamknij nawias klamrowy przecinek. Linia 4. otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Anna apostrof przecinek apostrof wiek apostrof dwukropek 19 zamknij nawias klamrowy przecinek. Linia 5. otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Anna apostrof przecinek apostrof wiek apostrof dwukropek 17 zamknij nawias klamrowy przecinek. Linia 6. otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Piotr apostrof przecinek apostrof wiek apostrof dwukropek 16 zamknij nawias klamrowy. Linia 7. zamknij nawias kwadratowy. Linia 9. print otwórz nawias okrągły sorted otwórz nawias okrągły slowniki przecinek key znak równości lambda uczen dwukropek uczen otwórz nawias kwadratowy apostrof wiek apostrof zamknij nawias kwadratowy zamknij nawias okrągły zamknij nawias okrągły.

Do funkcji anonimowej przekazywany jest każdy słownik w zmiennej uczen. Wyrażenie uczen["wiek"] pozwala wskazać wiek ucznia, który zostaje wykorzystany jako klucz sortowania.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Adam apostrof przecinek apostrof wiek apostrof dwukropek 16 zamknij nawias klamrowy przecinek otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Piotr apostrof przecinek apostrof wiek apostrof dwukropek 16 zamknij nawias klamrowy przecinek otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Anna apostrof przecinek apostrof wiek apostrof dwukropek 17 zamknij nawias klamrowy przecinek otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Ewa apostrof przecinek apostrof wiek apostrof dwukropek 18 zamknij nawias klamrowy przecinek otwórz nawias klamrowy apostrof imie apostrof dwukropek apostrof Anna apostrof przecinek apostrof wiek apostrof dwukropek 19 zamknij nawias klamrowy zamknij nawias kwadratowy.
Przykład 14

Ostatni przykład pokazuje sortowanie listy obiektów utworzonych na podstawie klasy Uczen, która ma dwa atrybuty, czyli imiewiek. Listę obiektów porządkujemy niemalejąco według wieku ucznia.

Linia 1. class Uczen dwukropek. Linia 2. def podkreślnik podkreślnik init podkreślnik podkreślnik otwórz nawias okrągły self przecinek imie przecinek wiek zamknij nawias okrągły dwukropek. Linia 3. self kropka imie znak równości imie. Linia 4. self kropka wiek znak równości wiek. Linia 6. def podkreślnik podkreślnik repr podkreślnik podkreślnik otwórz nawias okrągły self zamknij nawias okrągły dwukropek. Linia 7. return self kropka imie plus apostrof apostrof plus str otwórz nawias okrągły self kropka wiek zamknij nawias okrągły. Linia 9. obiekty znak równości otwórz nawias kwadratowy. Linia 10. Uczen otwórz nawias okrągły apostrof Adam apostrof przecinek 16 zamknij nawias okrągły przecinek. Linia 11. Uczen otwórz nawias okrągły apostrof Ewa apostrof przecinek 18 zamknij nawias okrągły przecinek. Linia 12. Uczen otwórz nawias okrągły apostrof Anna apostrof przecinek 19 zamknij nawias okrągły przecinek. Linia 13. Uczen otwórz nawias okrągły apostrof Anna apostrof przecinek 17 zamknij nawias okrągły przecinek. Linia 14. Uczen otwórz nawias okrągły apostrof Piotr apostrof przecinek 16 zamknij nawias okrągły. Linia 15. zamknij nawias kwadratowy. Linia 17. print otwórz nawias okrągły sorted otwórz nawias okrągły obiekty przecinek key znak równości lambda uczen dwukropek uczen kropka wiek zamknij nawias okrągły zamknij nawias okrągły.

Podobnie jak w poprzednich przykładach w funkcji anonimowej, do której trafia każdy obiekt w zmiennej uczen, możemy wskazać kryterium sortowania, tj. atrybut związany z wiekiem: uczen.wiek.

W definicji klasy metoda specjalna __repr__() wykorzystywana jest do zwrócenia reprezentacji obiektu, w tym przypadku do wypisania jego atrybutów, tj. imienia i wieku ucznia.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy Adam 16 przecinek Piotr 16 przecinek Anna 17 przecinek Ewa 18 przecinek Anna 19 zamknij nawias kwadratowy.

Podczas sortowania możemy również używać funkcji porównującej (komparatora), która powinna zwracać wartość mniejszą od 0, jeżeli pierwszy element jest mniejszy od drugiego; wartość większą od 0, w przeciwnym przypadku lub wartość 0, kiedy elementy są równe. Użycie funkcji porównującej daje nam możliwość określania własnych reguł, które decydują, który z dwóch elementów uznajemy za większy.

Do wskazania funkcji porównującej w argumencie key wykorzystujemy funkcję cmp_to_key() z modułu functools. Jej argumentem jest nazwa funkcji porównującej.

Przykład 15

Oto przykład użycia funkcji cmp_to_key() do wskazania funkcji porównującej o nazwie porownaj() dla argumentu key:

Linia 1. from functools import cmp podkreślnik to podkreślnik key. Linia 3. def porownaj otwórz nawias okrągły a przecinek b zamknij nawias okrągły dwukropek. Linia 4. print otwórz nawias okrągły cudzysłów Porównuję dwukropek cudzysłów przecinek a przecinek cudzysłów i cudzysłów przecinek b przecinek end znak równości cudzysłów cudzysłów zamknij nawias okrągły. Linia 5. if a procent 2 znak równości znak równości 1 and b procent 2 znak równości znak równości 0 dwukropek. Linia 6. print otwórz nawias okrągły cudzysłów Zwracam minus 1 cudzysłów zamknij nawias okrągły. Linia 7. return minus 1. Linia 8. print otwórz nawias okrągły cudzysłów Zwracam 1 cudzysłów zamknij nawias okrągły. Linia 9. return 1. Linia 11. lista znak równości otwórz nawias kwadratowy 1 przecinek 2 przecinek 3 przecinek 4 przecinek 5 przecinek 6 zamknij nawias kwadratowy. Linia 12. print otwórz nawias okrągły sorted otwórz nawias okrągły lista przecinek key znak równości cmp podkreślnik to podkreślnik key otwórz nawias okrągły porownaj zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły.

Wynik działania programu:

Linia 1. Porównuję dwukropek 2 i 1 Zwracam 1. Linia 2. Porównuję dwukropek 3 i 2 Zwracam minus 1. Linia 3. Porównuję dwukropek 3 i 2 Zwracam minus 1. Linia 4. Porównuję dwukropek 3 i 1 Zwracam 1. Linia 5. Porównuję dwukropek 4 i 3 Zwracam 1. Linia 6. Porównuję dwukropek 4 i 2 Zwracam 1. Linia 7. Porównuję dwukropek 5 i 2 Zwracam minus 1. Linia 8. Porównuję dwukropek 5 i 3 Zwracam 1. Linia 9. Porównuję dwukropek 6 i 5 Zwracam 1. Linia 10. Porównuję dwukropek 6 i 4 Zwracam 1. Linia 11. otwórz nawias kwadratowy 1 przecinek 3 przecinek 5 przecinek 2 przecinek 4 przecinek 6 zamknij nawias kwadratowy.

Wypisywane komunikaty oznaczają, że funkcja porownaj() otrzymuje pary liczb, które mają być uporządkowane. Funkcja zwraca wartość -1, jeżeli warunek a % 2 == 1 and b % 2 == 0 jest prawdziwy, czyli pierwsza liczba (a) jest parzysta i mniejsza od drugiej liczby parzystej (b), która jest większa. W pozostałych przypadkach zwracana jest wartość 1, co oznacza, że pierwsza liczba (a) jest większa.

W efekcie otrzymujemy listę, w której na początku znajdują się uporządkowane niemalejąco liczby nieparzyste, a potem również uporządkowane niemalejąco liczby parzyste.

list.sort()

Biblioteka standardowa zawiera również definicję funkcji sort() dostępnej jako metoda każdej listy. Metoda ta nie zawraca nowej listy, natomiast modyfikuje kolejność elementów listy, na rzecz której jest wywoływana. Wykorzystuje wspominany już algorytm stabilnego sortowania hybrydowego TimsorttimsortTimsort.

W metodzie sort() możemy korzystać z dwóch opcjonalnych nazwanych argumentów, tj. reverse oraz key. Ich działanie jest takie samo jak w przypadku funkcji sorted(). Poniżej zamieszczamy kilka przykładów.

Przykład 16

Domyślne sortowanie listy liczb całkowitych niemalejąco z użyciem metody sort(), która modyfikuje początkową listę.

Linia 1. lista znak równości otwórz nawias kwadratowy 5 przecinek 8 przecinek minus 3 przecinek 1 przecinek 10 przecinek 3 kropka 14 przecinek 18 zamknij nawias kwadratowy. Linia 2. lista kropka sort otwórz nawias okrągły zamknij nawias okrągły. Linia 3. print otwórz nawias okrągły lista zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy minus 3 przecinek 1 przecinek 3 kropka 14 przecinek 5 przecinek 8 przecinek 10 przecinek 18 zamknij nawias kwadratowy.
Przykład 17

Sortowania listy liczb całkowitych nierosnąco z użyciem metody sort(). Dodatkowy argument reverse ustawiony na wartość True pozwala uzyskać sortowanie nierosnące.

Linia 1. lista znak równości otwórz nawias kwadratowy 5 przecinek 8 przecinek minus 3 przecinek 1 przecinek 10 przecinek 3 kropka 14 przecinek 18 zamknij nawias kwadratowy. Linia 2. lista kropka sort otwórz nawias okrągły reverse znak równości True zamknij nawias okrągły. Linia 3. print otwórz nawias okrągły lista zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy 18 przecinek 10 przecinek 8 przecinek 5 przecinek 3 kropka 14 przecinek 1 przecinek minus 3 zamknij nawias kwadratowy.
Przykład 18

Sortowanie listy liczb całkowitych nierosnąc0 z użyciem metody sort(). Podobnie jak w przypadku omawianej wyżej funkcji sorted(), w przykładzie używamy dodatkowego argumentu key i funkcji anonimowej lambda. Funkcja zwraca wartość True, jeżeli sortowana liczba jest parzysta, co oznacza, że należy traktować ją jako większą niż liczba nieparzysta, dla której funkcja zwraca wartość False. W ten sposób uzyskamy takie samo uporządkowanie jak w omawianym wyżej przykładzie użycia własnej funkcji porównującej, tzn. wartości uporządkowane zostaną niemalejąco, ale na początku znajdą się liczby nieparzyste, a potem parzyste.

Linia 1. lista znak równości otwórz nawias kwadratowy 1 przecinek 2 przecinek 3 przecinek 4 przecinek 5 przecinek 6 przecinek 7 przecinek 8 przecinek 9 przecinek 10 zamknij nawias kwadratowy. Linia 2. lista kropka sort otwórz nawias okrągły key znak równości lambda x dwukropek x procent 2 znak równości znak równości 0 zamknij nawias okrągły. Linia 3. print otwórz nawias okrągły lista zamknij nawias okrągły.

Wynik działania programu:

Linia 1. otwórz nawias kwadratowy 1 przecinek 3 przecinek 5 przecinek 7 przecinek 9 przecinek 2 przecinek 4 przecinek 6 przecinek 8 przecinek 10 zamknij nawias kwadratowy.
Już wiesz

Funkcja sorted() jest przydatna, gdy chcemy uzyskać posortowaną kopię listy. Metody sort() użyjemy, kiedy chcemy posortować listę początkową, bez tworzenia jej kopii.

Słownik

biblioteka standardowa
biblioteka standardowa

biblioteka dostarczana z kompilatorem lub interpreterem danego języka programowania, zawierająca jego podstawowe funkcje i typy danych

dyrektywa
dyrektywa

polecenie dla kompilatora, które wykonuje on przed rozpoczęciem przez niego tworzenia kodu programu

funkcja wbudowana
funkcja wbudowana

funkcje danego języka programowania dostępne dla programisty w dowolnym momencie wykonywania programu

introsort
introsort

hybrydowy niestabilny algorytm sortujący, który w celu minimalizacji czasu wykonania wykorzystuje trzy algorytmy sortujące: sortowanie szybkie, sortowanie przez kopcowanie i sortowanie przez wstawianie

funkcja anonimowa
funkcja anonimowa

definicja funkcji bez nazwy, której używa się zazwyczaj raz; w języku Python używa się składni: lambda argumenty: wyrażenie; funkcja może mieć wiele argumentów, natomiast tylko jedno wyrażenie, którego wynik zwraca

komparator
komparator

interfejs lub klasa definiująca funkcję, która umożliwia porównywanie obiektów tej samej klasy

kontener danych
kontener danych

złożona struktura danych służąca do przechowywania obiektów udostępniająca metody pozwalające na dodawanie, odczytywanie, usuwanie, modyfikowanie czy wyszukiwanie danych, przykładem może być tablica lub lista

obiekt
obiekt

instancja jakiejś klasy definiującej złożony typ danych, zawiera pola z danymi (atrybuty) oraz funkcje wykonujące operacje na tych danych, zwane metodami

przeciążanie metod
przeciążanie metod

mechanizm języka programowania pozwalający na tworzenie wielu funkcji o tej samej nazwie, ale różniących się od siebie liczbą lub typem przyjmowanych argumentów

rzutowanie, konwersja typu
rzutowanie, konwersja typu

wyrażenie zmieniające typ danych danej komórki pamięci

timsort
timsort

stabilny algorytm sortowania łączący cechy sortowania przez wstawianie i przez scalanie; wyszukuje w danych już posortowane sekwencje i wykorzystuje je do wydajniejszego sortowania pozostałych danych

typ prosty
typ prosty

inaczej typ prymitywny, podstawowy w danym języku typ danych, np.: byte (tylko Java), short, int, long, float, double, charboolean (Java) / bool (C++); typy proste służą do przechowywania pojedynczych wartości

typ złożony
typ złożony

w kontekście tego materiału złożone typy danych rozumieć należy jako definiowane przy użyciu typów prostych klasy lub struktury użytkownika; tworzone na ich podstawie obiekty mogą przechowywać wiele wartości i udostępniać różne operacje; tak rozumiane typy złożone należy odróżnić od kontenerów, w których obiekty można zapisywać, np. tablic, list czy słowników

stabilny algorytm sortowania
stabilny algorytm sortowania

algorytm stabilny podczas porządkowania dwóch takich samych elementów zachowuje ich porządek wejściowy w uporządkowanym zbiorze wynikowym, algorytm niestabilny nie gwarantuje zachowania takiego porządku