Sortowanie przez wstawianie: tak jak układacie karty w ręku
Ile porównań i zamian kosztuje uporządkowanie listy?
Podręcznik: s. 139–148.
Rozgrzewka · 3 minuty
Po co komu porządek?
Wracamy do poprzedniej lekcji, tej o wyszukiwaniu sekwencyjnym i binarnym.
Wyszukiwanie sekwencyjne sprawdza komórki po kolei, od pierwszej. Co robi zamiast tego wyszukiwanie binarne?
Wyszukiwanie binarne działa tylko wtedy, gdy zbiór spełnia jeden warunek. Jaki to warunek?
Uporządkowanie danych kosztuje czas. Dlaczego mimo to często się opłaca?
podręcznik s. 133–139
Część 1 · Problem sortowania
Porównaj sąsiadów i zamień
Porządkowanie (sortowanie) to problem, dla którego opisano co najmniej kilkanaście algorytmów. Żaden z nich nie jest najszybszy w każdej sytuacji. Zaczynamy od najprostszego.
Sortowanie bąbelkowe (ang. bubble sort) porównuje parę sąsiednich elementów, zaczynając od pierwszej pary na liście, i zamienia je miejscami, gdy stoją w niewłaściwej kolejności. Taka zamiana sąsiadów to operacja prostej zamiany, dlatego metodę nazywa się też sortowaniem przez prostą zamianę.
Specyfikacja problemu sortowania. Dane: liczba naturalna n i n-elementowa lista A liczb całkowitych. Wynik: lista A po uporządkowaniu, czyli A[0] ≤ A[1] ≤ … ≤ A[n-1].
Ciekawostka: sortowanie da się zatańczyć. Na kanale AlgoRythmics w serwisie YouTube węgierski zespół folkowy pokazuje algorytmy w tańcu, na przykład w filmie „Bubble-sort with Hungarian (Csángó) folk dance”.
Podręcznik Informatyka na czasie 2, s. 139–140 (9.4 Algorytmy sortowania, ramka „Specyfikacja”; 9.5 Sortowanie bąbelkowe, definicja i operacja prostej zamiany) · ciekawostka: ramka „A to ciekawe” ze s. 140, film sprawdzony pod adresem youtube.com/watch?v=lyZQPjUT5B4
Część 1 · Przykład krok po kroku
Pięć liczb, cztery etapy
Porządkujemy listę 6, 4, 9, 1, 5 niemalejąco, czyli tak, żeby każda kolejna liczba była większa od poprzedniej albo jej równa. Pierwszy etap ustawia największą liczbę na ostatniej pozycji. W drugim etapie pomijamy już ostatni element, w trzecim dwa ostatnie, w czwartym trzy.
Podręcznik Informatyka na czasie 2, s. 141 (9.5 Sortowanie bąbelkowe, algorytm na przykładzie listy 6, 4, 9, 1, 5)
Część 1 · Lista kroków i kod
Dwie pętle, jedna w drugiej
Wczytaj listę liczb A.
Dla wartości i równych kolejno 1, 2, …, n-1 powtarzaj kroki 3 oraz 4.
Dla wartości j równych kolejno 0, 1, …, n-i-1 powtarzaj krok 4.
Jeśli A[j] > A[j+1], to zamień te elementy miejscami.
1. def bubble_sort(A):
2. n = len(A)
3. for i in range(1, n):
4. for j in range(0, n-i):
5. if A[j] > A[j+1]:
6. A[j], A[j+1] = A[j+1], A[j]
Pętle zagnieżdżone (ang. nested loops) to pętle umieszczone wewnątrz innych pętli. Zewnętrzna liczy etapy i wykonuje się n-1 razy, wewnętrzna robi porównania w jednym etapie. Każdy etap ustawia jedną liczbę na docelowym miejscu, więc w następnym etapie porównań jest o jedno mniej.
Podręcznik Informatyka na czasie 2, s. 142 (9.5 Sortowanie bąbelkowe, pojęcie pętli zagnieżdżonych, lista kroków, kod źródłowy funkcji bubble_sort)
Część 1 · Zamiana miejscami
Jak zamienić dwie wartości?
Dwóch wartości nie da się zamienić wprost: jeśli od razu wpiszemy 4 do A[j], to szóstka przepadnie. Dlatego najpierw chowamy jedną z nich w zmiennej pomocniczej.
W linii 6. kodu Python robi to samo krócej: A[j], A[j+1] = A[j+1], A[j]. Po prawej stronie znaku równości powstaje krotka (ang. tuple), czyli odpowiednik listy, którego nie da się zmieniać. Python zapamiętuje w niej obie wartości i dopiero potem wpisuje je na zamienione miejsca. Rada z podręcznika: żeby porządkować nierosnąco, zmieńcie w warunku znak „>” na „<”.
Podręcznik Informatyka na czasie 2, s. 142 (9.5 Sortowanie bąbelkowe, opis linii 6. i pojęcie krotki, ramka „Dobra rada”) · w podręczniku jest tylko wersja z krotką
Część 2 · Sortowanie przez wstawianie
Jak układacie karty w ręku?
Sortowanie przez wstawianie (ang. insertion sort) przegląda kolejne elementy listy od lewej i przenosi je w odpowiednie miejsce uporządkowanego już fragmentu po lewej stronie. Dokładnie tak układa się karty do gry: kartę podniesioną ze stołu wsuwacie między te, które już macie ułożone.
Podręcznik Informatyka na czasie 2, s. 143–145 (9.6 Sortowanie przez wstawianie: definicja, rys. 9.12 układanie kart, etapy dla listy 6, 4, 9, 1, 5 ze s. 144, podział listy na część posortowaną i nieposortowaną)
Część 2 · Kod i porównanie
Funkcja insertion_sort
1. def insertion_sort(A):
2. n = len(A)
3. for i in range(1, n):
4. temp = A[i]
5. j = i - 1
6. while j >= 0 and A[j] > temp:
7. A[j+1] = A[j]
8. j -= 1
9. A[j+1] = temp
Linia 4.: w zmiennej temp chowamy liczbę, dla której szukamy miejsca.
Linia 6.: warunek ze słowem and to koniunkcja, oba warunki muszą być prawdziwe naraz.
Python sprawdza je po kolei i odpuszcza drugi, gdy pierwszy jest fałszywy. To leniwe wartościowanie.
Linia 8.: j -= 1 to krótszy zapis j = j - 1.
Oba algorytmy sortują w miejscu: nie budują drugiej listy na wynik.
Podręcznik Informatyka na czasie 2, s. 145–146 (9.6 Sortowanie przez wstawianie: lista kroków, kod źródłowy funkcji insertion_sort, koniunkcja i leniwe wartościowanie, ramki „Warto wiedzieć” o operacjach w miejscu i o szybkości)
Ćwiczenie · na kartce · 12 minut
Ćwiczenie: sortujesz ręcznie
Podpisz kartkę. Uporządkuj niemalejąco listę A = [3, 0, 1, 7, 5, 2] sortowaniem bąbelkowym. Po każdym etapie zapisz stan listy oraz liczbę porównań i zamian, a na dole zsumuj obie kolumny.
Dla listy C = [8, 2, 3, 5] wykonaj jeden etap sortowania przez wstawianie: co trafia do temp, co przesuwasz, jaka jest lista po etapie.
Dla chętnych (dom): zapisz funkcję bubble_sort ze slajdu 5 w pliku sorting.py i uruchom ją na własnej liście.
Dla najszybszych: sortowanie przez wybór
Sortowanie przez wybór (ang. selection sort). Lista dzieli się na część uporządkowaną i nieuporządkowaną. W każdym etapie szukasz najmniejszej liczby w części nieuporządkowanej i zamieniasz ją miejscami z pierwszą liczbą tej części, a granica między częściami przesuwa się o jedno miejsce w prawo. Porównań jest tyle samo co w bąbelkowym, czyli n·(n-1)/2, ale zamian najwyżej n-1: jedna na etap. Dlatego ten algorytm wygrywa tam, gdzie zapis danych jest kosztowny. Opis mam z en.wikipedia.org/wiki/Selection_sort, podręcznik go nie omawia.
Podręcznik Informatyka na czasie 2, s. 142 (ćwiczenie 7), s. 145 (ćwiczenie 9) i s. 147 (zadanie 8)
Część 3 · Zamknięcie rozdziału
Gdzie to wróci po szkole?
To ostatnia lekcja rozdziału o algorytmice. Podręcznik zamyka go czterema scenariuszami zawodowymi.
Inżynier geodeta. Na pierwszym roku politechniki masz zajęcia z programowania. Znasz ze szkoły konstrukcje programistyczne, typy danych i proste struktury danych, więc rozumiesz omawiane algorytmy, choć język jest inny.
Inżynier pożarnictwa. Piszesz instrukcje na wypadek pożaru w biurowcu. Muszą być precyzyjne, więc zapisujesz je jako listę kroków, znaną Ci z lekcji programowania.
Staż w kancelarii adwokackiej. Akta nie są posegregowane. W uporządkowanym zbiorze łatwiej wyszukiwać, więc sortujesz je: najpierw chronologicznie, potem alfabetycznie.
Firma meblarska. Na szkoleniu z systemu ze sztuczną inteligencją pokazują model sztucznego neuronu z kodem źródłowym. Do zrozumienia go wystarcza wiedza o instrukcji warunkowej i pętlach.
Podręcznik Informatyka na czasie 2, s. 148 („Z informatyką w przyszłość”, Algorytmika i programowanie w języku Python, cztery scenariusze zawodowe)
Część 3 · Pytania kontrolne
Trzy pytania na koniec
Na czym polega operacja prostej zamiany i dlaczego sortowanie bąbelkowe bierze od niej drugą nazwę?
Skąd w funkcji bubble_sort biorą się dwie pętle, jedna w drugiej, i dlaczego wewnętrzna robi w każdym kolejnym etapie o jedno porównanie mniej?
Po co sortowaniu przez wstawianie zmienna pomocnicza temp? Co stałoby się bez niej?
Podręcznik Informatyka na czasie 2, s. 140–146 (9.5 Sortowanie bąbelkowe, 9.6 Sortowanie przez wstawianie, ramki „Zapamiętaj”)
Część 3 · Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
Sortowanie bąbelkowe pisane od zera
Nikt nie pisze go po to, żeby uporządkować dane. Zostaje jako ćwiczenie na zrozumienie algorytmu.
zastąpione
Własna funkcja sortująca
W Pythonie sortuje gotowa funkcja sorted(), która oddaje nową listę, i metoda list.sort(), która działa w miejscu.
narzędzia
Wybór jednego algorytmu
Pod spodem pracuje algorytm hybrydowy: dokumentacja Pythona nazywa go Timsort i pisze, że korzysta z porządku już obecnego w danych.
rozszerzane
Sortowanie przez wstawianie
Wraca w rozwiązaniach hybrydowych: przy krótkich fragmentach listy jest szybkie, więc kończy nim sortowanie szybkie.
nadal w użyciu
Porządkowanie listy liczb
W sklepie internetowym to sortowanie wyników po cenie, a w bazie danych sortowanie wyniku kwerendy z rozdziału o bazach.
nadal w użyciu
Wiersze o funkcjach sorted() i list.sort() oraz o algorytmie Timsort: dokumentacja Pythona, docs.python.org/3/howto/sorting.html (sprawdzone) · sortowanie przez wstawianie w ostatniej fazie sortowania szybkiego: podręcznik s. 146 (ramka „Warto wiedzieć”)