Podstawy informatyki 2 - PB Wydział Elektryczny
Transkrypt
Podstawy informatyki 2 - PB Wydział Elektryczny
Podstawy informatyki 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr II, studia stacjonarne Rok akademicki 2006/2007 Wykład nr 13 (06.06.2007) dr inŜ. Jarosław Forenc Podstawy informatyki 2 Wykład nr 13 Plan wykładu nr 13 Sortowanie Notacja O Klasyfikacje algorytmów sortowania Algorytmy sortowania sortowanie sortowanie sortowanie sortowanie sortowanie przez proste wstawianie przez proste wybieranie bąbelkowe szybkie (Quick-Sort) „zwariowane” i „głupie” dr inŜ. Jarosław Forenc 2/37 Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 3/37 Sortowanie sortowanie polega na uporządkowaniu zbioru danych względem pewnych cech charakterystycznych kaŜdego elementu tego zbioru najczęstszym przypadkiem jest sortowanie względem wartości kaŜdego elementu, np. sortowanie liczb, sortowanie słów w przypadku liczb, sortowanie polega na znalezieniu kolejności liczb zgodnej z relacją ≤ lub ≥ Przykład: tablica nieposortowana: tablica posortowana zgodnie z relacją ≤ (od najmniejszej do największej liczby): tablica posortowana zgodnie z relacją ≥ (od największej do najmniejszej liczby): Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 4/37 Sortowanie w przypadku słów (nazw) sortowanie polega na ustawieniu ich w porządku słownikowym (lub alfabetycznym) zwanym takŜe leksykograficznym Przykład: tablica nieposortowana: tablice posortowane: porównanie nazw moŜe być sprowadzone do porównywania ich liczbowych kodów Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 5/37 Sortowanie w praktyce sortowanie sprowadza się do porządkowanie danych na podstawie porównania - element stosowany w porównaniu nazywa się kluczem Przykład: tablica nieposortowana (imię, nazwisko, wiek): tablica posortowana (klucz - nazwisko): tablica posortowana (klucz - wiek): Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 6/37 Sortowanie Po co stosować sortowanie? posortowane elementy moŜna szybciej zlokalizować posortowane elementy moŜna przedstawić w bardziej czytelny sposób, np. kolejność alfabetyczna nazwisk przedstawienie cen produktów od najniŜszej do najwyŜszej posortowanie ułatwia wstawienie nowego elementu z zachowaniem porządku Klasyfikacje algorytmów sortowania złoŜoność obliczeniowa algorytmu - zaleŜność liczby wykonywanych operacji w stosunku do liczebności sortowanego zbioru n algorytmy proste („naiwne”) mają złoŜoność O(n2), dobre algorytmy mają złoŜoność O(n log n), idealna złoŜoność to O(n) oceniając wydajność algorytmu często analizuje się najgorszy (złoŜoność pesymistyczna), najlepszy i średni (złoŜoność średnia) przypadek Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 7/37 Notacja O notacja O stosowana jest do porównywania wydajności róŜnych algorytmów notacja ta wyraŜa złoŜoność matematyczną algorytmu w notacji tej po literze O występuje wyraŜenie w nawiasach zawierające literę n, która oznacza liczbę elementów, na której działa algorytm za miarę „dobroci” algorytmu przyjmuje się liczbę wykonywanych w nim elementarnych operacji, np. dodawanie, mnoŜenie, porównywanie Przykład: O(n) - złoŜoność algorytmu jest prostą funkcją liczby elementów - (jeśli sortowanie 1000 elementów zajmuje 1 s, to sortowanie - (2000 elementów zajmie 2 s) O(n2) - czas konieczny do wykonania algorytmu rośnie wraz z kwadratem - liczby elementów Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 8/37 Notacja O porównanie najczęściej występujących złoŜoności: Elementy O(log n) O(n) O(n log n) O(n2) O(2n) 10 3 10 33 100 1024 100 7 100 664 10 000 1,27⋅1030 1 000 10 1 000 9 966 1 000 000 1,07⋅10301 10 000 13 10 000 132 877 100 000 000 1,99⋅103010 O(log n) - złoŜoność logarytmiczna O(n) - złoŜoność liniowa O(n log n) - złoŜoność liniowo-logarytmiczna O(n2) - złoŜoność kwadratowa O(2n) - złoŜoność wykładnicza Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 9/37 Notacja O Uwagi: przy porównywaniu róŜnych wyraŜeń O(n) stałe nie mają znaczenia i mogą być ignorowane, np. połączenie algorytmów o róŜnych złoŜonościach tworzy algorytm o wyŜszej z połączonych złoŜoności, np. O(2n2) i O(9n2) mogą być rozwaŜane jak O(n2) dołączenie algorytmu o złoŜoności O(n2) do algorytmu o złoŜoności O(n) tworzy algorytm o złoŜoności O(n2) zagłębianie algorytmów (tj. mnoŜenie ich wpływu) tworzy algorytm z pomnoŜoną złoŜonością, np. algorytm O(n) zagłębiony w O(log n) daje w wyniku O(n log n) Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 10/37 Klasyfikacje algorytmów sortowania ZłoŜoność pamięciowa: złoŜoność pamięciowa jest to wielkość zasobów zajmowanych przez algorytm w algorytmach wykorzystujących technikę sortowania w miejscu (ang. in-place) wielkość zestawu danych podczas sortowania nie zmienia się (lub jest tylko nieco większa) algorytmy nie wykorzystujące techniki sortowania w miejscu wymagają podczas sortowania znaczniej więcej miejsca w pamięci komputera do przechowywania danych moŜe to być problemem, gdy zestaw danych do sortowania jest bardzo duŜy zwiększenie zapotrzebowania na pamięć związane jest takŜe z występowaniem rekurencji w algorytmach sortowania Sortowanie zewnętrzne i wewnętrzne: sortowanie zewnętrzne (sortowanie plików) jest to rodzaj algorytmów sortowania, które są stosowane, gdy nie jest moŜliwe jednoczesne umieszczenie wszystkich elementów zbioru sortowanego w pamięci komputera sortowanie wewnętrzne odbywa się w pamięci komputera Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 11/37 Klasyfikacje algorytmów sortowania Stabilność algorytmu: algorytm jest nazywany stabilnym, jeśli podczas sortowania zachowuje kolejność występowania elementów o tym samym kluczu Przykład: tablica nieposortowana (imię, nazwisko, wiek): tablica posortowana algorytmem stabilnym (klucz - wiek): tablica posortowana algorytmem niestabilnym (klucz - wiek): Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 12/37 Metody sortowania Uwagi do opisu algorytmów sortowania: w opisie algorytmów sortowania będą uŜywane tablice liczb całkowitych wartość kaŜdego sortowanego elementu jest jednocześnie kluczem sortowania analizując daną metodę będziemy brali pod uwagę liczbę porównań, w której uczestniczą elementy sortowanej tablicy Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 13/37 Sortowanie przez proste wstawianie sortowanie przez proste wstawianie (ang. insertion sort) jest podstawowym algorytmem sortowania, łatwym do zrozumienia i implementacji algorytm polega na pobieraniu kolejnego elementu z danych wejściowych i wstawianiu go na odpowiednie miejsce w wynikach Algorytm metody: elementy są umownie podzielone na ciąg wynikowy: a1,a2,…,ai-1 i ciąg źródłowy: ai,ai+1,…,an w i-tym kroku pobieramy element z ciągu źródłowego ai porównujemy ten element z kolejnymi elementami z ciągu wynikowego: ai-1,ai-2,… porównywanie kończymy, gdy porównywany element jest mniejszy lub równy elementowi ai lub dojdziemy do początku ciągu wynikowego wstawiamy element ai w odpowiednim miejscu ciągu wynikowego Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 14/37 Sortowanie przez proste wstawianie Przykład: Funkcja w języku C: void InsertionSort(int tab[]) { int i,j,tmp; for (i=1; i<N; i++) { j=i; tmp=tab[i]; while (tab[j-1]>tmp && j>0) { tab[j]=tab[j-1]; j--; } tab[j]=tmp; } } Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 15/37 Sortowanie przez proste wstawianie Uwagi: złoŜoność algorytmu: O(n2) w najgorszym przypadku kaŜdy element powoduje jednokrotne przestawienie wszystkich poprzedzających go elementów, a wtedy liczba porównań wynosi: n⋅(n-1) liczba porównań zaleŜna jest od początkowego rozmieszczenia elementów w tablicy + + + + + wydajny dla danych wstępnie posortowanych – mała efektywność dla normalnej i duŜej ilości danych wydajny dla zbiorów o niewielkiej liczebności małe zasoby zajmowane podczas pracy (sortowanie w miejscu) stabilny - zachowuje oryginalną kolejność takich samych elementów prosty w implementacji Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 16/37 Sortowanie przez proste wybieranie sortowanie przez proste wybieranie (ang. selection sort), nazywane takŜe sortowaniem przez selekcję, jest jedną z prostszych metod sortowania metoda ta polega na wyszukaniu elementu, który ma się znaleźć na zadanej pozycji i na zamianie miejscami z tym elementem, który jest tam obecnie Algorytm metody: zaczynając od elementu pierwszego, szukamy w tablicy elementu o najmniejszej wartości po znalezieniu takiego elementu zamieniamy go miejscami z pierwszym elementem następnie szukamy elementu najmniejszego zaczynając od drugiego elementu po znalezieniu elementu o najmniejszej wartości zamieniamy go z drugim elementem powtarzamy powyŜsze operacje do momentu, aŜ w tablicy pozostanie tylko jeden element Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 17/37 Sortowanie przez proste wybieranie Przykład: Funkcja w języku C: void SelectionSort(int tab[]) { int i,j,k,tmp; for (i=0;i<N-1;i++) { k=i; for (j=i+1; j<N; j++) if (tab[k]>tab[j]) k = j; tmp = tab[i]; tab[i] = tab[k]; tab[k] = tmp; } } Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 18/37 Sortowanie przez proste wybieranie Uwagi: złoŜoność algorytmu: O(n2) + + + szybki w sortowaniu niewielkich tablic – liczba porównań elementów jest niezaleŜna od początkowego rozmieszczenia elementów w tablicy (takie zachowanie algorytmu nazywane jest neutralnym lub niewraŜliwym) – w algorytmie moŜe zdarzyć się, Ŝe wykonywana jest zamiana tego samego elementu ze sobą (sytuacja taka występuje, gdy najmniejszy element jest na pierwszej pozycji) – w przedstawionej postaci algorytm jest niestabilny (nie zachowuje oryginalnej kolejności takich samych elementów) małe zasoby zajmowane podczas pracy (sortowanie w miejscu) prosty w implementacji Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 19/37 Sortowanie przez proste wybieranie Uwagi: uczynienie algorytmu stabilnym wymaga tylko jednej zmiany w kodzie programu /* algorytm niestabilny */ /* algorytm stabilny */ for (i=0;i<N-1;i++) { k=i; for (j=i+1; j<N; j++) if (tab[k]>tab[j]) k = j; tmp = tab[i]; tab[i] = tab[k]; tab[k] = tmp; } for (i=0;i<N-1;i++) { k=i; for (j=i+1; j<N; j++) if (tab[k]>=tab[j]) k = j; tmp = tab[i]; tab[i] = tab[k]; tab[k] = tmp; } algorytm moŜna przyspieszyć, jeśli wyszukiwać będziemy jednocześnie minimum i maksimum, a tabela będzie wypełniana z obu końców jeśli w kaŜdym kroku będziemy szukali elementu maksymalnego, to tablica zostanie posortowana od największego do najmniejszego elementu Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 20/37 Sortowanie bąbelkowe sortowanie bąbelkowe (ang. bubble sort), nazywane takŜe sortowaniem pęcherzykowym lub sortowaniem przez prostą zamianę (ang. straight exchange) polega na porównywaniu dwóch kolejnych elementów i zamianie ich kolejności jeśli jest to konieczne nazwa metody wzięła się stąd, Ŝe kolejne porównania powodują „wypychanie” kolejnego największego elementu na koniec („wypłynięcie największego bąbelka”) Algorytm metody: porównujemy pierwszy i drugi element tabeli i jeśli trzeba to zamieniamy je miejscami, następnie porównujemy drugi i trzeci element i jeśli jest to konieczne, to zamieniamy je miejscami, itd. powyŜsze operacje wykonujemy, aŜ dojdziemy do końca tabeli następnie ponownie rozpoczynamy porównywanie elementów od początku tabeli (element pierwszy z drugim, drugi z trzecim, itd. aŜ dojdziemy do końca tabeli) sortowanie kończymy, gdy podczas kolejnego przejścia przez całą tabelę nie wykonana zostanie Ŝadna zamiana elementów Podstawy informatyki 2 Wykład nr 13 Sortowanie bąbelkowe - przykład dr inŜ. Jarosław Forenc 21/37 Podstawy informatyki 2 Wykład nr 13 Sortowanie bąbelkowe Funkcja w języku C: void BubbleSort(int tab[]) { int i,j,tmp,koniec; do { koniec=0; for (i=0;i<N-1;i++) if (tab[i]>tab[i+1]) { tmp=tab[i]; tab[i]=tab[i+1]; tab[i+1]=tmp; koniec=1; } } while (koniec); } dr inŜ. Jarosław Forenc 22/37 Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 23/37 Sortowanie bąbelkowe Uwagi: złoŜoność algorytmu: O(n2) + + + prosta realizacja – mała efektywność wysoka efektywność uŜycia pamięci (sortowanie w miejscu) stabilny algorytm - zachowuje oryginalną kolejność takich samych elementów Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 24/37 Sortowanie szybkie (Quick-Sort) algorytm opracowany przez C.A.R. Hoare’a Algorytm metody: sortowanie odbywa się w dwu fazach: dzielenia i sortowania w fazie dzielenia tablica jest dzielona na dwie części wokół pewnego elementu (nazywanego elementem centralnym) wybieramy jeden element (losowo, choć moŜe to być element środkowy) i nazywamy go x przeglądamy tablicę od lewej strony, aŜ znajdziemy element ai ≥ x, a następnie przeglądamy tablicę od prawej strony, aŜ znajdziemy aj < x zamieniamy elementy ai i aj miejscami i kontynuujemy proces przeglądania i zamiany, aŜ nastąpi gdzieś spotkanie w środku tablicy w rezultacie otrzymujemy tablicę podzieloną na lewą część z wartościami mniejszymi od x i na prawą część z wartościami większymi od x Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 25/37 Sortowanie szybkie (Quick-Sort) Algorytm metody (cd.): na tym kończy się faza podziału i rozpoczyna faza sortowania faza sortowania zawiera dwa rekurencyjne wywołania tej samej funkcji sortowania: dla lewej i dla prawej części posortowanej tablicy rekurencja zatrzymuje się, gdy wielkość tablicy do posortowania wynosi 1 Przykład: sortujemy 6-elementową tablicę tab: wywołanie funkcji QuickSort() ma postać: QuickSort(tab,0,5); Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 26/37 Sortowanie szybkie (Quick-Sort) Przykład: - dla QuickSort(tab,0,5): wyznaczamy element środkowy: (0+5)/2 = 2, x = tab[2] = 5 od lewej szukamy tab[i] ≥ x, a od prawej tab[j] ≤ x, zamieniamy elementy miejscami poszukiwania kończymy, gdy indeksy mijają się wywołujemy rekurencyjnie funkcję QuickSort() dla elementów z zakresów [l,j] i [i,r]: QuickSort(tab,0,3); QuickSort(tab,4,5); Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 27/37 Sortowanie szybkie (Quick-Sort) Przykład: - dla QuickSort(tab,0,3): wyznaczamy element środkowy dla zakresu [0,3]: (0+3)/2 = 1, x = tab[1] = 2 od lewej szukamy tab[i] ≥ x, a od prawej tab[j] ≤ x, zamieniamy elementy miejscami: poszukiwania kończymy, gdy indeksy mijają się: wywołujemy rekurencyjnie funkcję QuickSort() tylko dla elementów z zakresu [2,3], gdyŜ po lewej stronie rozmiar tablicy do posortowania wynosi 1: QuickSort(tab,2,3); Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 28/37 Sortowanie szybkie (Quick-Sort) Przykład: - dla QuickSort(tab,4,5): wyznaczamy element środkowy dla zakresu [4,5]: (4+5)/2 = 4, x = tab[4] = 6 od lewej szukamy tab[i] ≥ x, a od prawej tab[j] ≤ x, zamieniamy elementy miejscami: poszukiwania kończymy, gdy indeksy mijają się: rozmiar obu tablic do posortowania wynosi 1 więc nie ma nowych wywołań Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 29/37 Sortowanie szybkie (Quick-Sort) Przykład: - dla QuickSort(tab,2,3): wyznaczamy element środkowy dla zakresu [2,3]: (2+3)/2 = 2, x = tab[2] = 3 od lewej szukamy tab[i] ≥ x, a od prawej tab[j] ≤ x, zamieniamy elementy miejscami: poszukiwania kończymy, gdy indeksy mijają się: rozmiar obu tablic do posortowania wynosi 1 więc nie ma nowych wywołań Podstawy informatyki 2 Wykład nr 13 Sortowanie szybkie (Quick-Sort) Funkcja w języku C: void QuickSort(int tab[], int l, int r) { int i,j,x,y; i=l; j=r; x=tab[(l+r)/2]; do { while (tab[i]<x) i++; while (x<tab[j]) j--; if (i<=j) { y=tab[i]; tab[i]=tab[j]; tab[j]=y; i++; j--; } } while (i<j); if (l<j) QuickSort(tab,l,j); if (i<r) QuickSort(tab,i,r); } dr inŜ. Jarosław Forenc 30/37 Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 31/37 Sortowanie szybkie (Quick-Sort) Wybór elementu centralnego: wybór elementu centralnego ma bardzo duŜy wpływ na szybkość sortowania maksymalne korzyści są osiągane wtedy, gdy element centralny jest medianą wszystkich wartości w tablicy - tablica dzielona jest w takim przypadku na dwie równe części wybrać moŜna dowolny element, gdyŜ waŜna jest jego wartość, a nie połoŜenie w tablicy nie jest zalecane wybieranie elementu pierwszego lub ostatniego w tablicy, gdyŜ w przypadku posortowanej tablicy taki wybór spowoduje największe koszty Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 32/37 Sortowanie szybkie (Quick-Sort) Uwagi: złoŜoność algorytmu: O(n log n) - dla średniego przypadku O(n2) - dla najgorszego przypadku + wysoka efektywność dla średniego przypadku – – – bardzo mała efektywność dla najgorszego przypadku ilość danych umieszczanych na stosie moŜna nieznacznie zmniejszyć poprzez przekazywanie do funkcji QuickSort() zamiast: - tablicy danych, dolnego i górnego zakresu danych - QuickSort(tab,left,right) przekazać tylko: - adres początku zaktualizowanej tablicy i całkowitą liczbę elementów, które pozostały do posortowania w tej części tablicy - QuickSort(tab,n) duŜe zasoby zajmowane w trakcie pracy (duŜo danych na stosie) niestabilny algorytm (nie zachowuje oryginalnej kolejności takich samych elementów) Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 33/37 Sortowanie szybkie - funkcja qsort() w języku C algorytm sortowania szybkiego został zaimplementowany w języku C w funkcji: QSORT stdlib.h void qsort(void *baza, size_t n, size_t size, (*funkcja)(const void *element1, const void *element2)); funkcja qsort() sortuje metodą Quick-Sort tablicę wskazywaną przez argument baza i zawierającą n elementów o rozmiarze size funkcja qsort() posługuje się funkcją porównującą funkcja(), której argumentami są wskazania do elementów tablicy baza funkcja() powinna zwracać wartości: < 0, gdy *element1 < *element2 == 0, gdy *element1 == *element2 > 0, gdy *element1 > *element2 Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 34/37 Funkcja qsort() w języku C - przykład (1/2) /* Name: w13_03_qsort.c Copyright: Politechnika Białostocka, Wydział Elektryczny Author: Jarosław Forenc ([email protected]) Date: 06-06-2007 Description: Zastosowanie funkcji bibliotecznej qsort() #include #include #include #define <stdio.h> <stdlib.h> <time.h> N 10 void generuj(int tab[]) { int i; srand(time(NULL)); for (i=0;i<N;i++) tab[i]=rand()%100; } void drukuj(int tab[]) { int i; for (i=0;i<N;i++) printf("%2d ",tab[i]); printf("\n"); } */ Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 35/37 Funkcja qsort() w języku C - przykład (2/2) 6 7 31 22 66 int funkcja(const void *element1, const void *element2) { qsort: if (*(int*)element1 < *(int*)element2) return -1; 6 7 22 22 0; 26 if (*(int*)element1 == *(int*)element2) return if (*(int*)element1 > *(int*)element2) return 1; } int main() { int tab[N]; generuj(tab); drukuj(tab); printf("\nqsort:\n"); qsort((void*)tab,(size_t)N,sizeof(int),funkcja); drukuj(tab); system("PAUSE"); return (0); } 89 22 27 26 52 27 31 52 66 89 Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 36/37 Sortowanie zwariowane algorytm opiera się na losowym sortowaniu zbioru - przestawiamy losowo elementy w zbiorze i sprawdzamy czy zbiór jest posortowany w algorytmie zwariowanym musimy rozwiązać zatem dwa problemy: sprawdzenie posortowania elementów oraz losowe potasowanie jedyną metodą sprawdzenia posortowania elementów jest porównanie ze sobą wszystkich sąsiednich elementów losowe potasowanie moŜna wykonać w ten sposób, Ŝe losujemy dwa numery elementów, a następnie elementy o tych numerach zamieniamy miejscami - jeśli operację tą powtórzymy wystarczającą ilość razy to zawartość zbioru zostanie potasowana pesymistyczna złoŜoność algorytmu: O(n⋅n!) Podstawy informatyki 2 Wykład nr 13 dr inŜ. Jarosław Forenc 37/37 Sortowanie głupie sortowanie głupie jest bardzo mało wydajnym algorytmem, ale daje poprawne wyniki przeglądamy kolejne pary elementów, jeśli są w złej kolejności to zamieniamy te elementy miejscami i rozpoczynamy operację porównywania elementów od początku zbioru złoŜoność algorytmu: O(n3)