Wróć do informacji o e-podręczniku Wydrukuj Pobierz materiał do PDF Pobierz materiał do EPUB Pobierz materiał do MOBI Zaloguj się, aby dodać do ulubionych Zaloguj się, aby skopiować i edytować materiał Zaloguj się, aby udostępnić materiał Zaloguj się, aby dodać całą stronę do teczki

Algorytm sortowania szybkiego

Sortowanie szybkie polega na wybraniu elementu rozdzielającego (tzw. pivotpivotpivot) oraz podzieleniu tablicy zawierającej dane na dwie części. W jednej zostają umieszczone elementy o wartościach większych niż pivot, w drugiej zaś — elementy o wartościach od niego mniejszych. Następnie elementy mniejsze i większe sortowane są osobno według tej samej zasady. Sortowanie odbywa się rekurencyjnierekurencjarekurencyjnie do momentu, gdy każda z podtablic zostanie uporządkowana. Dokładne omówienie algorytmu sortowania szybkiego zostało przedstawione w e‑materiale Sortowanie szybkiePpzx1YyemSortowanie szybkie.

Zadanie 1. Wystawa obrazów

W pewnym muzeum organizowana jest wystawa obrazów poświęconych figurom geometrycznym. Okoliczne muzea wypożyczyły placówce części własnych ekspozycji pasujących do tematyki wystawy.

Zadanie 1.1

Muzeum chce ustalić, w którym roku powstało najwięcej dzieł z obecnej wystawy. Obrazy te zostaną oprawione w złote ramy.

Plik lata.txt zawiera 76 wierszy zawierających rok powstania poszczególnych obrazów pokazywanych na wystawie (każdy rok zapisano w osobnym wierszu).

RiSqOKT4xRxSX

Przycisk umożliwiający pobranie pliku TXT z treścią zadania.

Plik TXT o rozmiarze 456.00 B w języku polskim

Napisz program, który wyznaczy rok, z którego pochodzi najwięcej dzieł, oraz wskaże, ile złotych ram na obrazy z tego roku powinno przygotować muzeum. Przyjmij, że jest tylko jeden rok z maksymalną liczbą powstałych dzieł. Zapisz obie wartości do pliku ramy.txt.

Do oceny oddajesz:

  • plik ramy.txt zawierający odpowiedź (rok, w którym powstało najwięcej prezentowanych obrazów, oraz liczbę złotych ram potrzebnych do ich oprawienia)

  • plik(i) z komputerową realizacją zadania (kodem programu)

Praca domowa

Przedstaw rozwiązanie zadania w postaci programu w wybranym języku (C++, Java lub Python). Zadbaj o prawidłowe wczytanie i zapisanie danych z/do pliku tekstowego. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.

Rozwiązanie

Rozwiązanie zadania przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z wybranego języka programowania: C++, Java lub Python.

W celu łatwiejszego zliczenia obrazów pochodzących z danego roku, posortujemy dane z pliku. Użyjemy do tego algorytmu sortowania szybkiego.

Ważne!

W przedstawionym algorytmie jako punkt rozdzielający przyjmuje się ostatnią wartość w tablicy.

Linia 1. funkcja sortowanie podkreślnik szybkie otwórz nawias okrągły Lata otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 2. jeżeli lewy otwórz nawias ostrokątny prawy dwukropek. Linia 3. punkt podkreślnik podziału ← podział otwórz nawias okrągły Lata przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 4. sortowanie podkreślnik szybkie otwórz nawias okrągły Lata przecinek lewy przecinek punkt podkreślnik podziału minus 1 zamknij nawias okrągły. Linia 5. sortowanie podkreślnik szybkie otwórz nawias okrągły Lata przecinek punkt podkreślnik podziału plus 1 przecinek prawy zamknij nawias okrągły.
  1. Definiujemy funkcję, która będzie dzielić tablicę na dwie części, a następnie sortować je osobno. [linia 1]

  2. Sprawdzamy, czy tablica, którą mamy podzielić, nie jest jednoelementowa (jeżeli jest, indeksyindeks komórkiindeksy lewyprawy są sobie równe). [linia 2]

  3. Wyznaczamy punkt podziału (pivot); jednocześnie zapisujemy dane w tablicy z uwzględnieniem punktu podziału. [linia 3]

  4. Rekurencyjnie uruchamiamy funkcję podziału dla utworzonych podtablic. [linie 4, 5]

Linia 1. funkcja podział otwórz nawias okrągły Lata otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 2. pivot ← Lata otwórz nawias kwadratowy prawy zamknij nawias kwadratowy. Linia 3. mniejsza ← lewy minus 1. Linia 4. dla większa znak równości lewy przecinek lewy plus 1 przecinek kropka kropka kropka prawy minus 1 wykonuj dwukropek. Linia 5. jeżeli Lata otwórz nawias kwadratowy większa zamknij nawias kwadratowy otwórz nawias ostrokątny pivot dwukropek. Linia 6. mniejsza ← mniejsza plus 1. Linia 7. zamień Lata otwórz nawias kwadratowy mniejsza zamknij nawias kwadratowy z Lata otwórz nawias kwadratowy większa zamknij nawias kwadratowy. Linia 8. zamień Lata otwórz nawias kwadratowy mniejsza plus 1 zamknij nawias kwadratowy z Lata otwórz nawias kwadratowy prawy zamknij nawias kwadratowy. Linia 9. zwróć otwórz nawias okrągły mniejsza plus 1 zamknij nawias okrągły.
  1. Definiujemy funkcję podziału, która będzie ustawiać wartości mniejsze niż pivot po lewej stronie tablicy, zaś wartości większe - po prawej; następnie funkcja zwróci pozycję wartości rozdzielającej tablicę. [linia 1]

  2. Ustawiamy pozycję elementu rozdzielającego oraz wartość zmiennej mniejsza. Pamiętajmy o tym, że przed zamianą pozycji komórek (w linii 7) dokonujemy inkrementacjiinkrementacjainkrementacji wartości zmiennej mniejsza, a zatem musimy nadać jej wartość o 1 mniejszą od pierwszej sprawdzanej pozycji. [linie 2, 3]

  3. Inicjujemy pętlę, w której wartość większa będzie odpowiadać kolejnym indeksom tabeli. [linia 4]

  4. Sprawdzamy w każdej iteracji pętliiteracja pętliiteracji pętli, czy wartość w tablicy dla indeksu większa ma wartość mniejszą niż pivot. Jeżeli tak, inkrementujemy wartość zmiennej mniejsza, a następnie zamieniamy miejscami komórkikomórka tablicykomórki o indeksach większamniejsza. [linie od 5 do 7]

  5. Wstawiamy pivot w odpowiednie miejsce w tablicy — tak, by wszystkie elementy po lewej stronie były od niego mniejsze, a wszystkie po prawej — większe. [linia 8]

  6. Zwracamy pozycję pivota i kończymy działanie funkcji. [linia 9]

Przejdźmy do właściwej części zadania. Na początku wczytujemy i sortujemy dane. Następnie zapisujemy algorytm, który przeszukuje posortowaną tablicę, by znaleźć rok powstania największej liczby obrazów oraz wskazać liczbę potrzebnych do ich oprawienia złotych ram:

Linia 1. Lata otwórz nawias kwadratowy 0 kropka kropka 75 zamknij nawias kwadratowy ← wczytaj dane z pliku cudzysłów lata kropka txt cudzysłów. Linia 2. sortowanie podkreślnik szybkie otwórz nawias okrągły Lata przecinek 0 przecinek długość otwórz nawias okrągły Lata zamknij nawias okrągły minus 1 zamknij nawias okrągły. Linia 4. rok ← Lata otwórz nawias kwadratowy 0 zamknij nawias kwadratowy. Linia 5. liczba ← 1. Linia 6. maks podkreślnik rok ← rok. Linia 7. maks podkreślnik liczba ← 1. Linia 9. dla i znak równości 1 przecinek 2 przecinek kropka kropka kropka przecinek długość otwórz nawias okrągły Lata zamknij nawias okrągły minus 1 wykonuj dwukropek. Linia 10. jeżeli Lata otwórz nawias kwadratowy i zamknij nawias kwadratowy znak równości rok dwukropek. Linia 11. liczba ← liczba plus 1. Linia 12. w przeciwnym razie dwukropek. Linia 13. rok ← Lata otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 14. liczba ← 1. Linia 16. jeżeli liczba zamknij nawias ostrokątny znak równości maks podkreślnik liczba dwukropek. Linia 17. maks podkreślnik liczba ← liczba. Linia 18. maks podkreślnik rok ← rok. Linia 20. zapisz maks podkreślnik rok maks podkreślnik liczba do pliku cudzysłów ramy kropka txt cudzysłów.
  1. Wczytujemy dane z pliku. [linia 1]

  2. Wywołujemy funkcję, w której został zaimplementowany algorytm sortowania szybkiego. Jako dane wejściowe podajemy: tablicę lat, pozycję, od której należy rozpocząć sortowanie, oraz pozycję końcową. Tablice indeksujemy od zera, zgodnie z ich reprezentacją w komputerze. [linia 2]

  3. Deklarujemy potrzebne zmienne. [linie 4‑7]

  4. Korzystając z pętli, sprawdzamy poniższe warunki dla każdego roku:

    • jeżeli jest taki sam jak poprzednio rozpatrywany, dodajemy jedno wystąpienie do licznika wystąpień; [linia 11]

    • jeżeli jest inny niż poprzednio rozpatrywany, zapisujemy nowy rok jako aktualnie rozpatrywany i ustawiamy licznik wystąpień na 1. [linie 13‑14]

  5. Z każdą iteracją pętli sprawdzamy również, czy dany rok pojawia się najwięcej razy. Jeżeli tak, zapisujemy ten rok i liczbę jego wystąpień w odpowiednich zmiennych. [linie 16‑18]

  6. Na koniec zapisujemy wyniki do odpowiedniego pliku. [linie 20‑21]

Odpowiedź do zadania dla danych zapisanych w pliku tekstowym lata.txt:

RTTJM2gKIBe3p

Przycisk umożliwiający pobranie pliku TXT z odpowiedzią do zadania.

Plik TXT o rozmiarze 7.00 B w języku polskim

Zadanie 1.2

Po zakończeniu wystawy trzeba przygotować eksponaty do zwrócenia muzeom, z których zostały wypożyczone. Sporządzono w tym celu listę — numer każdego jej wiersza oznacza pozycję obrazu na wystawie, zaś w wierszu zapisany jest sześciocyfrowy kod z oznaczeniem danego muzeum i obrazu:

  • cyfry na pozycjach od 1. do 3. (od lewej strony) oznaczają numer muzeum,

  • cyfry na pozycjach od 4. do 6. to oznaczenie obrazu w danym muzeum.

Im większa jest liczba stanowiąca numer muzeum, tym dalej się ono znajduje. Obrazy należy ułożyć w takiej kolejności, aby najpierw zostały wysłane dzieła należące do najbardziej odległych muzeów. W rezultacie wszystkie eksponaty wrócą na swoje miejsce w podobnym czasie. Przyjmijmy, że z każdego muzeum wypożyczono tylko jeden obraz.

Plik lista.txt zawiera 76 liczb (każda zapisana w osobnym wierszu), stanowiących numery poszczególnych dzieł. Numery te się nie powtarzają.

Rz5YVlsKlg6sW

Przycisk umożliwiający pobranie pliku TXT z treścią zadania.

Plik TXT o rozmiarze 531.00 B w języku polskim

Napisz program, który uporządkuje obrazy w kolejności ich wysyłki oraz zapisze numery muzeów, do których wysyłane są obrazy, w pliku kolejność.txt.

Przykład 1

Dla danych wejściowych:

Linia 1. 114165. Linia 2. 158168. Linia 3. 130185. Linia 4. 125172.

- przykładowy zapis do pliku wynikowego będzie wyglądał następująco:

Linia 1. 158. Linia 2. 130. Linia 3. 125. Linia 4. 114.

Do oceny oddajesz:

  • plik kolejność.txt zawierający odpowiedź (liczby całkowite dodatnie będące numerami muzeów w odpowiedniej kolejności)

  • plik(i) z komputerową realizacją zadania (kodem programu)

Praca domowa

Przedstaw rozwiązanie zadania w postaci programu w wybranym języku (C++, Java lub Python). Zadbaj o prawidłowe wczytanie danych z pliku tekstowego do programu. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.

Rozwiązanie

Rozwiązanie przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z języków C++, Java lub Python.

Aby rozwiązać zadanie, musimy nieco zmienić kod, który przedstawiliśmy w podpunkcie 1.

W celu zmiany porządku sortowania na nierosnący należy zmodyfikować funkcję podział(), ponieważ to ona odpowiada za dzielenie elementów na podtablice mniejszych i większych elementów.

Ważne!

W pseudokodzie tablica Lata została zastąpiona tablicą Kod.

Linia 1. funkcja podział otwórz nawias okrągły Kod otwórz nawias kwadratowy zamknij nawias kwadratowy przecinek lewy przecinek prawy zamknij nawias okrągły. Linia 2. pivot ← Kod otwórz nawias kwadratowy prawy zamknij nawias kwadratowy. Linia 3. mniejsza ← lewy minus 1. Linia 4. dla większa znak równości lewy przecinek lewy plus 1 przecinek kropka kropka kropka prawy minus 1 wykonuj dwukropek. Linia 5. jeżeli Kod otwórz nawias kwadratowy większa zamknij nawias kwadratowy zamknij nawias ostrokątny pivot dwukropek. Linia 6. mniejsza ← mniejsza plus 1. Linia 7. zamień otwórz nawias okrągły Kod otwórz nawias kwadratowy mniejsza zamknij nawias kwadratowy przecinek Kod otwórz nawias kwadratowy większa zamknij nawias kwadratowy zamknij nawias okrągły. Linia 8. zamień otwórz nawias okrągły Kod otwórz nawias kwadratowy mniejsza plus 1 zamknij nawias kwadratowy przecinek Kod otwórz nawias kwadratowy prawy zamknij nawias kwadratowy zamknij nawias okrągły. Linia 9. zwróć otwórz nawias okrągły mniejsza plus 1 zamknij nawias okrągły.
  • Modyfikujemy wyrażenie warunkowe; sprawdzamy, czy liczba na pozycji wskazywanej przez indeks większa jest większa niż element rozdzielający. Jeżeli tak, postępujemy dalej tak samo jak w poprzednim zadaniu. [linia 5]

Po posortowaniu musimy dodatkowo umieścić trzy pierwsze cyfry każdego kodu w tablicy pomocniczej, którą zapiszemy w pliku kolejność.txt.

Linia 1. Kod otwórz nawias kwadratowy 0 kropka kropka 75 zamknij nawias kwadratowy ← wczytaj dane z pliku cudzysłów lista kropka txt cudzysłów. Linia 2. sortowanie podkreślnik szybkie otwórz nawias okrągły Kod przecinek 0 przecinek długość otwórz nawias okrągły Kod zamknij nawias okrągły minus 1 zamknij nawias okrągły. Linia 4. Pomocnicza otwórz nawias kwadratowy 0 kropka kropka długość otwórz nawias okrągły Kod zamknij nawias okrągły minus 1 zamknij nawias kwadratowy. Linia 5. dla i znak równości 0 przecinek 1 przecinek kropka kropka kropka przecinek długość otwórz nawias okrągły Kod zamknij nawias okrągły minus 1 wykonuj dwukropek. Linia 6. Pomocnicza otwórz nawias kwadratowy i zamknij nawias kwadratowy ← kod podkreślnik muzeum otwórz nawias okrągły Kod otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 8. zapisz Pomocnicza otwórz nawias kwadratowy 0 kropka kropka długość otwórz nawias okrągły Kod zamknij nawias okrągły minus 1 zamknij nawias kwadratowy do pliku cudzysłów kolejność kropka txt cudzysłów.
  • Po posortowaniu danych z pliku lista.txt umieszczamy kod każdego muzeum w tablicy pomocniczej. Korzystamy w tym celu z pomocniczej funkcji kod_muzuem() zdefiniowanej poniżej. [linie 4, 5, 6]

  • Zapisujemy kody poszczególnych muzeów w pliku kolejność.txt i kończymy działanie programu. [linia 8]

Linia 1. funkcja kod podkreślnik muzeum otwórz nawias okrągły kod zamknij nawias okrągły. Linia 2. kod ← kod div 1000. Linia 3. zwróć kod.
  1. Definiujemy funkcję, która będzie przekształcać sześciocyfrowy kod w liczbę trzycyfrową, złożoną z trzech pierwszych cyfr kodu. [linia 1]

  2. Kod dzielimy całkowicie przez tysiąc — pozbywamy się w ten sposób trzech ostatnich cyfr (pozostaje liczba trzycyfrowa). [linia 2]

  3. Zwracamy wartość zmiennej kod. [linia 3]

Odpowiedź do zadania dla danych zapisanych w pliku tekstowym lista.txt:

RusuxU5fZLtCs

Przycisk umożliwiający pobranie pliku TXT z odpowiedzią do zadania.

Plik TXT o rozmiarze 303.00 B w języku polskim
Ważne!

W pseudokodzie wykorzystaliśmy operator div, który jest operatorem dzielenia całkowitego.

Ważne!

W zadaniach maturalnych polegających na pisaniu programu w wybranym języku programowania zdający może stosować funkcje wbudowane wybranego przez siebie języka. Dla funkcji zwracającej posortowaną tablicę liczb całkowitych tab o długości n są to odpowiednio:

C++

Linia 1. sort otwórz nawias okrągły tab przecinek tab plus n zamknij nawias okrągły.

Java

Linia 1. Arrays kropka sort otwórz nawias okrągły tab zamknij nawias okrągły.

Python

Linia 1. sorted otwórz nawias okrągły tab zamknij nawias okrągły.

Słownik

indeks komórki
indeks komórki

numer (pozycja) komórki w tablicy

inkrementacja
inkrementacja

zwiększenie wartości zmiennej o jeden

iteracja pętli
iteracja pętli

inaczej: cykl pętli; pojedyncze wykonanie instrukcji zapisanych w pętli

komórka tablicy
komórka tablicy

kontener służący do przechowywania pojedynczego elementu tablicy

pivot
pivot

element sortowanej tablicy wybierany według określonego schematu (może to być np. element środkowy), ze względu na który tablica rozdzielana jest na podtablice - po lewej stronie tego elementu znajdują się wartości nie większe od pivota, a po prawej nie mniejsze od niego

rekurencja
rekurencja

technika programowania polegająca na odwoływaniu się procedur lub funkcji do samych siebie, aż do momentu spełnienia warunku podstawowego