DressCode: Sortowanie
Czas, który będzie Ci potrzebny na rozwiązanie całego zadania: co najmniej 8 godzin.
Jednym z najważniejszych zagadnień w informatyce jest sortowanie, czyli porządkowanie przedmiotów—rosnąco lub malejąco.
Przykładowo—w dzienniku szkolnym uczniowie są zazwyczaj posortowani (czyli uporządkowani) według nazwiska:
- Anielewicz Barbara
- Nemeczek Tomasz
- Tyczyński Zygmunt
- Zalewska Anna
W informatyce powiemy, że nazwisko Anielewicz „jest mniejsze” od Nemeczek (gdyż litera A jest w alfabecie przed literą N).
Różne zbiory obiektów (np. ludzi, czy przedmioty) można sortować względem róznych kryteriów (np. rozmiaru/wzrostu, nazwy). Na przykład mając trzy zwierzęta:
psa:
, konia:
i
jeża:
możemy posortować je względem ich wielkości:
albo po nazwie (alfabetycznie):
Istnieje wiele różnych sposobów (algorytmów) sortowania obiektów. Twoim zadaniem będzie napisać program, który będzie porządkować obiekty przy użyciu sortowania bąbelkowego—jednego z łatwiejszych do zrozumienia algorytmów sortowania.
Co będzie Ci potrzebne
Program porządkujący „bąbelkowo” będziesz pisać przy użyciu języka JavaScript. Jest to język używany przez każdą przeglądarkę. Do rozwiązania zadania przyda Ci się znajomość jego podstaw. Aby je sobie przyswoić, polecamy Ci skorzystanie z jednego z poniższych kursów:
jeśli znasz język angielski (na poziomie VI klasy szkoły podstawowej powinno wystarczyć), polecamy Ci kurs CodeCademy—moduły od 1 (Introduction to JavaScript) do 5 (Control Flow);
jeśli wolisz kurs w języku polskim, polecamy Ci kurs Khan Academy— - sekcje „Podstawy Rysowania”, „Zmienne”, „Bonus: Zmiana rozmiaru za pomocą zmiennych”, „Funkcje”, „Logika i instrukcja if” oraz „Zapętlanie”. Kurs jest dostępny po polsku—jeśli wyświetla Ci się po angielsku, poszukaj opcji zmiany języka!
Uwaga! Którykolwiek kurs wybierzesz, powinnaś sobie zarezerwować na niego co najmniej 5 godzin. Tematy tłumaczone w tych kursach są bardzo ważne i mogą na początku nie być oczywiste—dlatego uzbrój się w cierpliwość i daj sobie troszkę czasu. Obiecujemy, nie będziesz żałować. :-)
Nie będziemy sprawdzać, czy wykonałaś jakiekolwiek zadania z kursu. Sugerujemy Ci te kursy, ponieważ będzie potrzebna Ci zawarta w nich wiedza.
Zadanie
Pobierz na swój komputer plik sortowanie.html.
Jeżeli otworzysz ten plik w przeglądarce (np. Chrome, Firefox, Safari,
Internet Explorer), zobaczysz prosty formularz, jednak pole „— wybierz
algorytm —” nie posiada żadnych opcji do wyboru przez co próba
rozpoczęcia demonstracji kończy się niepowodzeniem.
Twoim zadaniem jest stworzenie pliku algorytmy.js, w
którym zaimplementujesz algorytm sortowanie bąbelkowego.
Pobierz na swój komputer plik algorytmy.js—możesz
wykorzystać jego zawartość w swoim kodzie programu. Do edytowania pliku
wystarczy prosty edytor tekstu—taki jak Notatnik (Windows), TextEdit
(MacOS), czy gedit (Linux). Możesz użyć również bardziej zaawansowanych
edytorów—np. Atom czy Sublime Text, które podkreślą
składnię JavaScript. Po każdym zapisaniu zmiany w pliku
algoryrytmy.js odśwież otwarty w przeglądarce plik
sortowanie.html, tak by zobaczyć zmiany.
Dalej w instrukcji wyjaśnimy szczegółowo, na czym polegają różne algorytmy sortowania. Tymczasem poniższy film przedstawia, jak powinna wyglądać strona z kilkoma algorytmami sortowania:
Zajrzyj do pliku algorytmy.js—zawiera on trzy
przykładowe algorytmy. Nie porządkują one elementów, a jedynie pokazują
w jaki sposób na nich operować. Po rozwiązaniu zadania Twój plik
algorytmy.js powinien zawierać następujące wywołanie
funkcji zarejestrujAlgorytm:
zarejestrujAlgorytm(
'Sortowanie bąbelkowe',
function(rozmiar, porownaj, zamien) {
// … Twoja implementacja sortowania bąbelkowego …
}
);
Dostępne funkcje pomocnicze
W swoim kodzie możesz korzystać ze:
- zmiennej
rozmiar, - funkcji
porownaj(i, j)oraz - funkcji
zamien(i, j).
Zmienna rozmiar określa ile obiektów należy posortować.
Odpowiada ona polu „Liczba elementów” w formularzu.
Uwaga! Elementy są numerowane od zero. Oznacza to,
że pierwszy obiekt leży na pozycji o numerze 0, a ostatni
na pozycji rozmiar - 1. Próby operowania na elementach
spoza tego zakresu będą skutkować błędnym zakończeniem algorytmu.
Funkcja porownaj(i, j) porównuje element na pozycji
i z elementem na pozycji j. Jeżeli ten na
pozycji i jest mniejszy, wynikiem porównania jest
-1; jeżeli obiekty są sobie równe, wynikiem jest
0; jeżeli element na pozycji i jest większy,
wynikiem jest 1. W szczególności oznacza to, że:
porownaj(i, i) == 0orazporownaj(i, j) == -porownaj(j, i).
No i na koniec, funkcja zamien(i, j) zamienia elementy
na pozycji i oraz j miejscami. Funkcja działa
poprawnie również, gdy i oraz j są sobie
równe.
Dla przykładu, wyobraźmy sobie, że mamy do czynienia z tablicą
[3, 1, 1]. Wówczas:
rozmiar == 3,porownaj(0, 1) == 1(gdyż3 > 1),porownaj(1, 2) == 0(gdyż1 == 1),porownaj(2, 0) == -1(gdyż1 < 3) i jednocześnie- wywołanie
zamien(0, 2)zamieni tablicę do postaci[1, 1, 3].
Sortowanie przez wybór i wstawianie
Zanim przystąpisz do implementacji sortowania bąbelkowego, sugerujemy najpierw zaimplementować sortowanie przez wybór oraz sortowanie przez wstawianie. Na filmie załączonym powyżej, są to dwa pierwsze zaprezentowane algorytmy.
Sortowanie przez wybór
Gdy sortujemy przez wybór, wiele razy wyszukujemy (wybieramy) najmniejszy element na liście, a następnie przesuwamy go na początek listy. Potem wyszukujemy drugi najmniejszy element, trzeci najmniejszy, itd.
Algorytm można opisać następująco:
- Niech
i = 0. - Znajdź najmniejszy element spośród elementów
i…rozmiar-1i umieść go na pozycjii. W tym celu:- Niech
j = iorazmin = i. - Zwiększ
jo jeden. Jeżelij ≥ rozmiar, skocz do kroku 3. - Jeżeli element na pozycji
jjest mniejszy od tego na pozycjimin, niechmin = j. - Skocz do kroku ii.
- Niech
- Zamień element na pozycji
iz elementem na pozycjimin. - Zwiększ
io jeden. Jeżelii < rozmiar, skocz do kroku 2.
Sortowanie przez wstawianie
Gdy sortujemy przez wstawianie, robimy coś podobnego do porządkowania w ręce kart do gry (gdy dobieramy po jednej karcie z talii). Kolejne elementy z talii (czyli z końca naszej listy) wstawiamy na odpowiednie miejsce w ręce (czyli w naszej liście).
Algorytm można opisać następująco:
- Niech
i = 1. - Jeżeli
i ≥ rozmiar, zakończ algorytm. Tablica jest posortowana. - Wstaw element na pozycji
ina poprawną pozycję spośród elementów0…i. W tym celu:- Niech
j = i. - Zmniejsz
jo jeden. Jeżelij < 0, skocz do kroku 4. - Jeżeli element na pozycji
jnie jest większy od elementu na pozycjij+1, skocz do kroku 4. - Zamień elementy na pozycji
jorazj+1miejscami. - Skocz do kroku ii.
- Niech
- Zwiększ
io jeden. - Skocz do kroku 2.
Sortowanie bąbelkowe
Sortowanie bąbelkowe jest trochę bardziej skomplikowanym algorytmem. Nazwa wywodzi się od porównania do bąbelków powietrza poruszających się w górę w akwarium z wodą.
Gdy wykonujemy sortowanie bąbelkowe, porównujemy ze sobą kolejne pary sąsiadujących ze sobą elementów. Jeżeli są one w złej kolejności (czyli najpierw większy, potem mniejszy), zamieniamy je miejscami. Gdy wykonamy taką zamianę odpowiednio dużo razy, okaże się, że uporządkowaliśmy całą listę.
Algorytm wygląda następująco:
- Niech
n = rozmiar. - Wykonaj pojedyncze przejście „bąbelkowania”, w tym celu:
- Niech
i = 0. - Zwiększ
io jeden. Jeżelii ≥ rozmiar, skocz do kroku 3. - Jeżeli element na pozycji
ijest mniejszy od elementu na pozycjii - 1, zamień elementy miejscami. - Skocz do kroku ii.
- Niech
- Zmniejsz
no jeden. Jeżelin > 0, skocz do kroku 2.
Optymalizacje
Ale uwaga! Powyżej opisany algorytm można zoptymalizować przyśpieszając jego działanie.
Po każdym kolejnym przejściu wewnętrznej pętli (t.j. „bąbelkowania”), kolejne największe elementy umieszczane są na poprawnej pozycji. Fakt ten można wykorzystać modyfikując przejścia „bąbelkowania” tak, aby zamiast za każdym razem operować na elementach
0…rozmiar-1, operowała na elementach z zakresu0…n-1.Algorytm należy dodatkowo zmodyfikować w ten sposób, że powinien on zakończyć działanie jeżeli wewnętrzna pętla nie dokonała żadnych zamian. Dla przykładu, jeżeli elementy byłyby od razu uporządkowane, implementacja powyższego algorytmu pracowicie porównywałaby ze sobą elementy nie wykonując żadnych zamian miejsc.
Dla (jeszcze bardziej) ambitnych
Jeżeli zainteresował Cię temat sortowania, zachęcamy do implementacji innych algorytmów takich jak sortowanie szybkie, czy sortowanie przez kopcowanie.
Niestety z powodu limitacji kodu odpowiedzialnego za animacje, nie wszystkie algorytmy mogą zostać zaimplementowane. Np. sortowanie przez scalanie wymaga dodatkowej tymczasowej tablicy, czego skrypt nie udostępnia, a sortowanie kubełkowe wymaga znajomości wartości elementów.
Więcej o różnych algorytmach sortowania możesz dowiedzieć się tutaj.