Skrypt do Algorytmów i Struktur Danych K. Kleczkowski M. Pietrek 14 marca 2018
2
Spis tre±ci I Algorytmy 5 1. Algorytmy sortowania 7 1.1. Wprowadzenie...................................... 7 1.2. Sortowanie przez wstawianie.............................. 8 1.2.1. Algorytm wstawiania.............................. 8 1.2.2. Algorytm sortowania przez wstawianie.................... 8 1.2.3. Analiza zªo»ono±ci sortowania przez wstawianie............... 9 1.3. Sortowanie przez scalanie............................... 10 1.3.1. Algorytm scalania............................... 10 1.3.2. Algorytm sortowania przez scalanie...................... 12 1.3.3. Analiza zªo»ono±ci............................... 12 3
4 SPIS TRE CI
Cz ± I Algorytmy 5
Rozdziaª 1 Algorytmy sortowania Je±li co± jest gªupie i dziaªa, to nie jest gªupie. autor nieznany Uwa»a si,»e jednym z najbardziej fundamentalnych problemów le» cych u podstaw informatyki jest problem sortowania. W tym rozdziale zostan przedstawione jedne z najbardziej popularnych algorytmów sortowania. Zanim jednak podejmiemy si prób opisu tych algorytmów, przyda si teoretyczne wprowadzenie. 1.1. Wprowadzenie Wprowad¹my wa»ne denicje. Denicja 1.1.1 (Tablica). Niech D b dzie niepustym zbiorem. Tablic n-elementow (n N) o elementach ze zbioru D nazywamy sko«czony ci g A = (a 1, a 2, a 3,..., a n 1, a n ) D n. Uwaga. W przypadku podci gu (a i, a i+1, a i+2,..., a j 1, a j ) stosujemy oznaczenie A [a.. b], przy czym 1 i n, 1 j n oraz i j. W szczególno±ci A [1.. n] oznacza caª tablic n-elementow. Stosowa b dziemy równie» oznaczenie na i-ty element tej tablicy jako A [i]. Maj c zdeniowan tablic mo»emy sformuªowa nast puj cy problem. Problem 1.1.2 (Problem sortowania). Niech D b dzie niepustym zbiorem i A [1.. n] b dzie tablic n-elementow (n N) o elementach ze zbioru D. Niech porz dek b dzie porz dkiem liniowym na elementach ci gu A. Nale»y znale¹ tak permutacj σ : {1, 2,..., n} {1, 2,..., n},»e a σ(1) a σ(2) a σ(3)... a σ(n 1) a σ(n). Uwaga. W szczególno±ci b dziemy mówi krótko,»e n-elementowa tablica A jest posortowana wtedy, gdy a 1 a 2 a 3... a n 1 a n. Szerok klas algorytmów sortowania rozwi zuj cy problem sortowania s algorytmy, które wykorzystuj pewien porz dek liniowy, by uzyska» dan permutacj. Jednym z nich, który stosunkowo jest prosty w implementacji jest sortowanie przez wstawianie. 7
8 ROZDZIAŠ 1. ALGORYTMY SORTOWANIA 1.2. Sortowanie przez wstawianie Sortowanie przez wstawianie intuicyjnie odbywa si w taki sposób, w jaki ludzie ukªadaj karty. W ka»dym kroku ukªadania tych kart zostaje wstawiona karta do podtablicy ju» posortowanych kart. Jak przekonamy si pó¹niej, ten algorytm ªatwo zaimplementowa. 1.2.1. Algorytm wstawiania Omówmy sobie algorytm, który odpowiada za dziaªanie InsertionSorta. Jest to algorytm wstawiania do posegregowanej podtablicy A[1.. i] i-tego elementu tablicy A[1.. n], który b dziemy okre±la mianem Insert. Udowodnijmy wa»ny niezmiennik. Algorytm 1.2.1 Wstawianie do posortowanej podtablicy Require: The array A[1.. i 1] is already sorted. Ensure: The array A[1.. i] is already sorted. 1: procedure Insert(A[1.. i]) 2: let key A[i] 3: let j i 1 4: while j 1 A[j] > key do 5: A[j + 1] A[j] 6: j j 1 7: end while 8: A[j + 1] key 9: end procedure Niezmiennik 1.2.1. Dla ka»dej iteracji p tli (w linii 4) 0 j min j i 1 podtablica A[j + 1.. i] zawiera elementy wi ksze od klucza, przy czym j min = min{k : A[k] > key}. Dowód. Indukcja wzgl dem iteracji. Zaªó»my,»e j min i 1. W wypadku, gdy j min > i 1 klucz jest wstawiony trywialnie, bowiem jest on elementem maksymalnym w rozpatrywanej podtablicy. Sprawd¹my tez dla j = i 1. Poniewa» j min j oraz tablica A[1.. i 1] jest posortowana, to A[j min ] > key i nast pnie A[j min ] < A[i 1], czyli A[i 1] > key. Zatem po wykonaniu tego kroku mamy,»e A[i] A[i 1], czyli otrzymujemy,»e A[i] > key, innymi sªowy, tablica A[i.. i] speªnia tez. Zaªó»my teraz,»e dla pewnego k takiego,»e j min k i 1, podtablica A[k + 1.. i] jest posortowana i zawiera elementy wi ksze od klucza. Niech k = k 1 takie,»e j min k. Poniewa» j min k oraz tablica A[1.. i] jest posortowana, to A[j min ] > key i nast pnie A[j min ] < A[k ], czyli A[k ] > key. Wobec tego tablica zostanie przesuni ta o jeden element, to znaczy, A = (a 1, a 2,..., a jmin, a jmin+1,..., a k 1, a k, a k, a k +1,..., a i, a i+1,..., a n 1, a n ). Z zaªo»enia indukcyjnego podtablica A[k + 1.. i] ma elementy wi ksze od klucza. Poniewa» A[k] > key, to A[k.. i] = A[k + 1.. i] ma elementy wi ksze od klucza, co nale»aªo pokaza. 1.2.2. Algorytm sortowania przez wstawianie Maj c udowodniony algorytm wstawiania, mo»emy w prosty sposób uªo»y algorytm sortowania przez wstawianie.
1.2. SORTOWANIE PRZEZ WSTAWIANIE 9 Algorytm 1.2.2 Sortowanie przez wstawianie Require: n {k N : k 1} Ensure: The array A[1.. n] is already sorted. 1: procedure InsertionSort(A[1.. n]) 2: for i 2.. n do Insert(A[1.. i]) 3: end for 4: end procedure Niezmiennik 1.2.2. Dla ka»dego kroku 2 i n, tablica A[1.. i] jest posortowana. Dowód. Dzi ki niezmiennikowi 1.2.1, po wykonaniu algorytmu Insert otrzymujemy, i» j = j min 1 oraz podtablica A[j min + 1.. i] zawiera elementy wi ksze od klucza. Poniewa» tablica A[1.. i 1] jest posortowana, to A[j min 1] A[j min ] key i st d wstawiamy A[j + 1] key. Mamy wobec tego,»e tablica A[1.. i] jest posortowana, poniewa» A[j min 1] key A[j min + 1]. Dzi ki temu algorytm sortowania przez wstawianie sprawia,»e tablica A[1.. n] jest posortowana. 1.2.3. Analiza zªo»ono±ci sortowania przez wstawianie Wykonajmy analiz zªo»ono±ci pesymistycznej. Fakt 1.2.3. Czas dziaªania algorytmu 1.2.1 jest rz du O(i). Dowód. Niech tablica A[1.. i] b dzie posortowana odwrotnie, to znaczy a 1 > a 2 >... > a i 1 > a i. St d p tla (w linii 4) wykona si (i 1) j min + 1 razy, przy czym j min = 1, czyli i 1 razy. St d widzimy,»e i 1 = O(i). Fakt 1.2.4. Czas dziaªania algorytmu 1.2.2 jest rz du O(n 2 ). Dowód. Niech tablica A[1.. n] b dzie posortowana odwrotnie, to znaczy a 1 > a 2 >... > a n 1 > a n. St d procedura 1.2.1 wykona si n 1. St d widzimy,»e ( ) n i=2 O(i) = O n(n+1) 2 = O(n 2 ). Jak mo»na zauwa»y, algorytm jest niewydajny dla du»ych danych dzi ki zªo»ono±ci kwadratowej. Równie» poka»emy,»e dla przypadku ±redniego nadal nie otrzymujemy lepszej zªo»ono±ci. Zanim przejdziemy do analizy, przypomnijmy sobie z algebry nast puj ce denicje. Denicja 1.2.1. Permutacj π sko«czonego zbioru A jest bijekcja π : A A. Denicja 1.2.2. Niech (A, ) b dzie porz dkiem liniowym. Inwersj dla permutacji π : A A nazywamy par (i, j) A A tak,»e i < j oraz π(i) > π(j). Czytelnik mo»e si zastanawia, czemu potrzebne s nam inwersje w analizie zªo»ono±ci ±redniej. Nale»y zauwa»y,»e Obserwacja 1.2.5. Po wykonaniu algorytmu 1.2.1 liczba inwersji zmniejsza si o jeden. Algorytm 1.2.2 st d ko«czy prac, gdy liczba inwersji jest równa zero.
10 ROZDZIAŠ 1. ALGORYTMY SORTOWANIA Dowód tej obserwacji pozostawiamy jako wiczenie. St d mo»na spojrze na inwersje istniej ce w tablicy, która zostanie posortowana. Fakt 1.2.6. redni czas dziaªania algorytmu 1.2.2 wynosi Θ(n 2 ). Dowód. Niech A = (a 1, a 2,..., a n ) b dzie tablic oraz, π b dzie permutacj tak,»e a π(1) a π(2)... a π(n). Niech I i,j b dzie zmienn losow, która jest zadana wzorem. I i,j = { 1 i < j π(i) > π(j) 0 w p.w. Niech I = [ ] i<j I i,j. Z liniowo±ci warto±ci oczekiwanej mamy E[I] = E i<j I i,j = i<j E[I i,j]. Zauwa»my,»e je±li permutacja π ma inwersj i < j, to mo»na przyporz dkowa (π(1),..., π(i),... π(j),..., π(n)) (π(1),..., π(j),... π(i),..., π(n)) przy czym to przyporz dkowanie jest bijekcj. St d otrzymujemy,»e permutacji z inwersj i < j jest tyle samo, co bez inwersji, czyli mo»emy natra na ni z jednakowym prawdopodobie«- stwem P[I i,j = 1] = 1 2 dla dowolnych i < j. Oczywi±cie E[I i,j] = P[I i,j = 1] = 1 2. Uporz dkowanych par (i, j) mo»emy ustali na ( n 2) sposobów, poniewa» wystarczy wybra podzbiór dwuelementowy i z tego,»e mamy liniowy porz dek, mo»emy utworzy ci g rosn cy. Wobec tego mamy,»e E[I] = ( ) n 2 1 2 = n(n 1) 4 = Θ(n 2 ). To,»e algorytm ma zªo»ono± kwadratow, nie oznacza,»e jest nieprzydatny. Biegªy Czytelnik zawua»y,»e zªo»ono± pami ciowa tego algorytmu jest rz du O(1), czyli jest tani w kwestii u»ycia pami ci. Zatem algorytm nadaje si do maªych próbek danych oraz w technikach hybrydowych. 1.3. Sortowanie przez scalanie Sortowanie przez scalanie zostaªo opracowane przez Johna von Neumanna w roku 1945 [1]. Jest jednym z reprezentatywnych przykªadów algorytmów opartych o metod dziel i zwyci»aj. 1.3.1. Algorytm scalania Opiszemy tutaj algorytm scalania, który odpowiada za fraz zwyci»aj w naszej metodzie. Jest to algorytm, który nie jest algorytmem w miejscu, to znaczy, potrzebuje osobnej pami ci, by wykona scalanie. Niezmiennik 1.3.1. Dla ka»dego kroku p tli (w linii 4) 1 k min{n, m} tablica C[1.. k] jest posortowana i zawiera elementy tablic A[1.. i] lub A[1.. j]. Dowód. Indukcja wzgl dem iteracji p tli. Sprawd¹my dla k = 1. Mamy wobec tego po wykonaniu ciaªa C[1] = min{a[1], B[1]}, st d trywialnie mamy speªnion tez. Zaªó»my teraz,»e dla pewnego l takiego,»e 1 l min{n, m}, tablica C[1.. l] jest posortowana i zawiera elementy tablic A[1.. i] lub A[1.. j], gdzie 1 i n oraz 1 j m s ustalone.
1.3. SORTOWANIE PRZEZ SCALANIE 11 Algorytm 1.3.1 Zª czanie dwóch tablic Require: Arrays A[1.. n] and B[1.. m] are already sorted. Ensure: Returned array is already sorted and consists of A and B. 1: procedure Merge(A[1.. n], B[1.. m]) 2: let i 1, j 1, k 1 3: let C[1.. n + m] 4: while i n j m do 5: if A[i] B[j] then 6: C[k] A[i] 7: i i + 1 8: k k + 1 9: else 10: C[k] A[j] 11: j j + 1 12: k k + 1 13: end if 14: end while 15: while i n do 16: C[k] A[i] 17: i i + 1 18: k k + 1 19: end while 20: while j m do 21: C[k] A[j] 22: j j + 1 23: k k + 1 24: end while 25: return C 26: end procedure
12 ROZDZIAŠ 1. ALGORYTMY SORTOWANIA W kolejnym kroku l = l + 1 min{n, m} zostaje dodany element C[l ] = min{a[i], B[j]}. Poka»emy teraz,»e C[l] C[l ]. Poniewa» tablica C z zaªo»enia indukcyjnego jest posortowana, to C[l] jest maksymalnym elementem tablicy C[1.. l]. Poniewa» kresem górnym tablicy A[1.. i 1] jest A[i] oraz podobnie dla B[1.. j 1] jest B[j], to otrzymujemy,»e C[l] A[i] lub C[l] B[j], czyli C[l] C[l ], co nale»aªo dowie±. Fakt 1.3.2. Po wykonaniu algorytmu 1.3.1 speªniony jest warunek ko«cowy. Dowód. Poniewa» udowodnili±my prawdziwo± niezmiennika 1.3.1, to tablica C[1.. min{n, m}] zawiera elementy tablic A[1.. min{n, m}] lub B[1.. min{n, m}]. Je±li n = min{n, m}, to nale»y przekopiowa tablic B[min{n, m} + 1, m]. Istotnie, tablica B jest posortowana i mamy,»e C[min{n, m}] B[min{n, m} + 1]. Analogiczna sytuacja nast puje, gdy m = min{n, m}. 1.3.2. Algorytm sortowania przez scalanie Maj c udowodnion poprawno± algorytmu scalania mo»emy sformuªowa sam algorytm sortowania. Algorytm 1.3.2 Sortowanie przez scalanie Require: n {k N : k 1} Ensure: The array A[1.. n] is already sorted. 1: procedure MergeSort(A[1.. n]) 2: if n = 1 then 3: return 4: end if 5: let mid n 2 6: MergeSort(A[1.. mid]) 7: MergeSort(A[mid + 1.. n]) 8: let A Merge(A[1.. mid], A[mid + 1.. n]) 9: for i 1.. n do 10: A[i] A [i] 11: end for 12: end procedure Fakt 1.3.3. Po wykonaniu algorytmu 1.3.2 speªniony jest warunek ko«cowy dla ka»dego n 1. Dowód. Indukcja zupeªna wzgl dem wielko±ci tablicy. Dla n = 1 mamy trywialnie posortowan tablic. Zaªó»my,»e dla pewnego k 1 mamy,»e dla ka»dego k, l takiego,»e k k l 1 i k l, tablica A[l.. k] jest posortowana przez ów algorytm. Wobec tego, w szczególno±ci posortowane s A[1.. n 2 ] oraz A[ n 2 + 1.. k ]. Z warunku ko«cowego algorytmu 1.3.1 mamy,»e tablica A[1.. k ] jest posortowana, co nale»aªo dowie±. 1.3.3. Analiza zªo»ono±ci Przeanalizujmy czas algorytmu. Fakt 1.3.4. Czas wykonywania algorytmu 1.3.1 ze wzgl du na cz sto± zapisu do tablicy C jest rz du Θ(n + m).
1.3. SORTOWANIE PRZEZ SCALANIE 13 Dowód. Nale»y zauwa»y,»e p tla w linii 4 wykona si dokªadnie min{n, m} razy. Dodatkowo wykonywane s operacje kopiowania max{n, m} min{n, m} razy. Š czny koszt wynosi max{n, m} min{n, m} + min{n, m} = max{n, m} = Θ(n + m) Fakt 1.3.5. Czas wykonywania algorytmu 1.3.2 jest rz du Θ(n log n). Dowód. Mamy nast puj c funkcj czasu { 2T ( ) n T (n) = 2 + Θ(n) n > 1 Θ(1) n = 1 (1.3.1) Z twierdzenia o rekurencji uniwersalnej mamy,»e T (n) = Θ(n log n). Nale»y zauwa»y,»e czas ±redni, zarówno jak i optymistyczny jest taki sam, wynika to ze zªo-»ono±ci algorytmu scalania.
14 ROZDZIAŠ 1. ALGORYTMY SORTOWANIA
Bibliograa [1] Wikipedia. Merge sort. url: https://en.wikipedia.org/wiki/merge_sort. 15