Sortowanie - wybrane algorytmy Aleksandra Wilkowska Wydział Matematyki - Katedra Matematyki Stosowanej Politechika Wrocławska 2 maja 2018 1 / 39
Plan prezentacji Złożoność obliczeniowa Sortowanie bąbelkowe 1 Opis algorytmu 2 Przykład Quicksort 1 Metoda dziel i zwyciężaj 2 Opis algorytmu 3 Przykład Heapsort 1 Kopce 2 Tworzenie kopca 3 Rozbiór kopca 4 Sortowanie - algorytm 2 / 39
Złożoność obliczeniowa Definicja 1 (Złożoność obliczeniowa) Złożoność obliczeniowa to ilość zasobów komputerowych koniecznych do wykonania programu realizującego algorytm. Określamy ją jako funkcję danych wejściowych algorytmu. Definicja 2 (Notacja O ) Mówimy, że funkcja o złożoności obliczeniowej T (n) jest rzędu funkcji f(n)) jeśli potrafimy znaleźć takie n 0 N oraz takie c R, że dla każdego n n 0 prawdziwa jest nierówność: T (n) c f (n) 3 / 39
Złożoność obliczeniowa: pamięciowa i czasowa Definicja 3 (Złożoność obliczeniowa pamięciowa) Złożoność czasowa to ilość pamięci wykorzystanej w celu realizacji algorytmu, wyrażana w liczbie bajtów lub liczbie zmiennych typów elementarnych. Definicja 4 (Złożoność obliczeniowa czasowa) Jest to czas wykonania algorytmu wyrażany w standardowych jednostkach czasu, liczbie cykli procesora lub w liczbie wszystkich operacji. 4 / 39
Bubblesort - sortowanie bąbelkowe 1 Jest to jeden z prostszych algorytmów sortowania 2 Zasada działania opiera się na porównywaniu par sąsiadujących elementów i zamianie ich kolejności w przypadku nie spełnienia kryterium porządkowego 3 Złożoność obliczeniowa tego algorytmu to O(n 2 ) 5 / 39
Bubblesort - sortowanie bąbelkowe Opis algorytmu Dane wejściowe: S tablica liczb długości n 1 Dla każdego j = 1, 2,..., n 1 wykonaj krok 2 2 Dla każdego i = 1, 2,..., n 1: Jeśli S[i] > S[i + 1] S[i] S[i + 1] 3 Zakończ 6 / 39
Przykład sortowania bąbelkowego - 1 iteracja Rysunek 1: Algorytm - Quicksort / 39
Przykład sortowania bąbelkowego - 2 iteracja Rysunek 2: Algorytm - Quicksort 8 / 39
Przykład sortowania bąbelkowego - 3 iteracja Rysunek 3: Algorytm - Quicksort 9 / 39
Przykład sortowania bąbelkowego - 4 iteracja Rysunek 4: Algorytm - Quicksort 10 / 39
Quicksort - sortowanie szybkie 1 Jeden z najbardziej popularnych algorytmów sortowania 2 Wykorzystuje technikę dziel i zwyciężaj 3 Złożoność obliczeniowa tego algorytmu jest rzędu O(nlogn) 11 / 39
Metoda dziel i zwyciężaj Definicja 5 (Dziel i zwyciężaj) Dziel i zwyciężaj - jedna z głównych metod projektowania algorytmów w informatyce, prowadząca do bardzo efektywnych rozwiązań. W strategii tej problem dzieli się rekurencyjnie na dwa lub więcej mniejszych podproblemów tego samego (lub podobnego) typu tak długo, aż fragmenty staną się wystarczająco proste do bezpośredniego rozwiązania. Z kolei rozwiązania otrzymane dla podproblemów scala się, uzyskując rozwiązanie całego zadania. 12 / 39
Quicksort - sortowanie szybkie Dane wejściowe: S tablica liczb długości n. lewy/prawy - indeks pierwszego/ostatniego elementu w zbiorze 1 i = lewy+prawy 2 2 pivot S[i],S[i] S[d], j lewy 3 Dla i = lewy, lewy + 1,..., prawy 1 wykonaj: Sprawdź, czy d[i] pivot S[i] S[j], j j + 1 S[prawy] s[j], s[j] pivot 4 Jeśli lewy < j 1, to wywołaj algorym Quicksort(lewy,j-1) 5 Jeśli j + 1 < prawy to wywołaj algorym Quicksort(j+1,prawy) 13 / 39
Quicksort - sortowanie szybkie, krok 1 Rysunek 5: Algorytm - Quicksort 14 / 39
Quicksort - sortowanie szybkie, krok 2 Rysunek 6: Algorytm - Quicksort 15 / 39
Quicksort - sortowanie szybkie, krok 3 Rysunek : Algorytm - Quicksort 16 / 39
Heapsort - sortowanie przez kopcowanie 1 Jest nieco wolniejszy niż sortowanie szybkie 2 Jego przewagą jest lepsza pesymistyczna złożoność obliczeniowa O(nlogn) (dla Quicksort O(n 2 )) 3 Podstawą działania algorytmu jest użycie kolejki priorytetowej - kopca binarnego. 4 Algorytm składa się z dwóch faz: w pierwszej fazie elementy są przeorganizowane, aby utworzyć kopiec, w drugiej fazie dokonywane jest właściwe sortowanie. 1 / 39
Kopiec - definicja Tablicowa struktura danych reprezentująca drzewo binarne Kopiec typu max: wartość danego węzła niebędącego korzeniem jest zawsze mniejsza niż wartość jego rodzica Rysunek 8: Kopiec 18 / 39
Procedura tworzenia kopca z elementów zbioru Opis algorytmu Dane wejściowe: S zbiór zawierający elementy do wstawienia do kopca. 1 Dla i = 2,..., n wykonuj: 2 j i, k j div 2 3 x S[i] 4 Dopóki k > 0 i S[k] < x wykonuj 5 S[j] x S[j] S[k] j k k div 2 19 / 39
Procedura tworzenia kopca 5 9 6 8 10 5 Budowę kopca rozpoczynamy od pierwszego elementu zbioru, który staje się korzeniem. Następnie dołączamy następny element. Warunek kopca jest zachowany. 20 / 39
Procedura tworzenia kopca 6 8 10 9 5 9 5 Po dodaniu elementu 9 warunek kopca przestaje być spełniony. Aby przywrócić warunek kopca zamieniamy węzły i 9 miejscami. 21 / 39
Procedura tworzenia kopca 8 10 9 9 5 6 6 5 Dołączamy kolejny element 6. Warunek kopca przestaje być spełniony - zamieniamy miejscami węzły 5 i 6. 22 / 39
Procedura tworzenia kopca 8 10 9 9 6 5 5 6 Dołączamy kolejny element. Warunek kopca przestaje obowiązywać. Zamieniamy miejscami węzły 6 i. 23 / 39
Procedura tworzenia kopca 10 9 9 8 5 6 8 5 6 Dołączamy kolejny węzeł. Powoduje on naruszenie warunku kopca, zatem wymieniamy ze sobą węzły i 8. 24 / 39
Procedura tworzenia kopca 9 9 8 10 5 6 10 5 6 8 Dołączenie ostatniego elementu znów narusza warunek kopca. Zamieniamy miejscami węzeł 8 z węzłem 10. Jednak na najwyższym poziomie warunek kopca dalej jest naruszony. 25 / 39
Procedura tworzenia kopca 10 9 10 9 5 6 8 5 6 8 26 / 39
Procedura rozbierania kopca Opis algorytmu Dane wejściowe: S zbiór zawierający strukturę kopca. 1 Dla i = n, n 1..., 2 wykonuj: 2 S[1] S[i] 3 j 1, k 2 4 Dopóki k < i wykonuj Jeżeli (k + 1 < i) i S[k + 1] > S[k], wówczas m k+1, inaczej m k Jeżeli S[m] S[j], to wyjdź z pętli i kontynuuj od początku S[j] S[m] j m, k j+j 2 / 39
Procedura rozbioru kopca 9 2 8 8 1 5 4 2 1 5 4 9 Rozbiór kopca rozpoczynamy od korzenia, który usuwamy ze struktury kopca. W miejsce korzenia wstawiamy ostatni liść. 28 / 39
Procedura rozbioru kopca 8 8 2 4 1 5 4 1 5 2 9 Struktura kopca została zaburzona, idziemy zatem od korzenia w dół struktury przywracając warunek kopca - przodek większy lub równy od swoich potomków. 29 / 39
Procedura rozbioru kopca 8 2 4 4 1 5 2 1 5 9 8 Usuwamy z kopca kolejny korzeń zastępując go ostatnim liściem. 30 / 39
Procedura rozbioru kopca 2 4 5 4 1 5 1 2 9 8 Ponownie w nowym kopcu przywracamy warunek kopca. 31 / 39
Procedura rozbioru kopca 2 5 4 5 4 1 2 1 9 8 Usuwamy z kopca kolejny korzeń zastępując go ostatnim liściem. 32 / 39
Procedura rozbioru kopca 2 5 5 4 2 4 1 1 9 8 W nowym kopcu przywracamy warunek kopca. 33 / 39
Procedura rozbioru kopca 5 1 2 4 2 4 1 9 8 5 Usuwamy z kopca kolejny korzeń zastępując go ostatnim liściem i przywracamy warunek kopca. 34 / 39
Procedura rozbioru kopca 4 1 2 1 2 9 8 5 4 Usuwamy z kopca kolejny korzeń zastępując go ostatnim liściem i przywracamy warunek kopca. 35 / 39
Procedura rozbioru kopca 2 1 1 9 8 5 4 2 1 Usuwamy z kopca kolejny korzeń zastępując go ostatnim liściem. Po wykonaniu tej operacji usunięcia w kopcu pozostał tylko jeden element - usuwamy go. Usunięte z kopca elementy tworzą ciąg uporządkowany. 36 / 39
HeapSort - Sortowanie przez kopcowanie Opis algorytmu Dane wejściowe: S zbiór zawierający elementy do wstawienia do kopca. 1 Stwórz kopiec 2 Rozbierz kopiec 3 Zakończ 3 / 39
Podsumowanie Przedstawione zostały podstawowe algorytmu sortujące - istnieje wiele innnych algorytmów, jak również modyfikacje przedstawionych algorytmów. Złożoność obliczeniowa przedstawionych algorytmów jest najlepsza dla algorytmu Quicksort i Heapsort - O(nlogn). Heapsort ma lepszą złożoność obliczeniową w przypadku pesymistycznym. Złożonośc pamięciowa jest najmniejsza dla algorytmu Heapsort. 38 / 39
Bibliografia Cormen Thomas H., Leiserson Charles E., Rivest Ronald L, Clifford Stein, Wprowadzenie do algorytmów P.Wróblewski, Algorytmy. Struktury danych i techniki programowania J.Walaszek, http://eduinf.waw.pl/inf/alg/003 sort/index.php198 39 / 39