Pojęcia podstawowe. Złożonośd czasowa algorytmów. Rekurencja

Podobne dokumenty
Wybrane algorytmy tablicowe

Podstawy Informatyki. Sprawność algorytmów

ALGORYTMY I STRUKTURY DANYCH

3. Podaj elementy składowe jakie powinna uwzględniać definicja informatyki.

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Matematyczne Podstawy Informatyki

Algorytmika i pseudoprogramowanie

Algorytmy i Struktury Danych.

Wykład 2. Poprawność algorytmów

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

TEORETYCZNE PODSTAWY INFORMATYKI

Zaawansowane algorytmy i struktury danych

Projektowanie algorytmów rekurencyjnych

TEORETYCZNE PODSTAWY INFORMATYKI

Klasa 2 INFORMATYKA. dla szkół ponadgimnazjalnych zakres rozszerzony. Założone osiągnięcia ucznia wymagania edukacyjne na. poszczególne oceny

Analiza algorytmów zadania podstawowe

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Złożoność algorytmów. Wstęp do Informatyki

Algorytmy i Struktury Danych

Wstęp do programowania

Wprowadzenie do złożoności obliczeniowej

Zaliczenie. Egzamin. lub. Wykład. Zaliczenie. Ćwiczenie. 3 zadania. Projekty. Ocena. Na ocenę

1. Analiza algorytmów przypomnienie

Strategia "dziel i zwyciężaj"

Pierwsze kroki. Algorytmy, niektóre zasady programowania, kompilacja, pierwszy program i jego struktura

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

Wstęp do programowania

Algorytmy i Struktury Danych

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Kierunek i poziom studiów: Matematyka, studia I stopnia (licencjackie), rok I

Zasady analizy algorytmów

Złożoność obliczeniowa zadania, zestaw 2

Sortowanie - wybrane algorytmy

Technologie informacyjne Wykład VII-IX

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Teraz bajty. Informatyka dla szkół ponadpodstawowych. Zakres rozszerzony. Część 1.

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 13. Karol Tarnowski A-1 p.

Za pierwszy niebanalny algorytm uważa się algorytm Euklidesa wyszukiwanie NWD dwóch liczb (400 a 300 rok przed narodzeniem Chrystusa).

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 13. Karol Tarnowski A-1 p.

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Metodyka i Technika Programowania 1

Teoretyczne podstawy informatyki

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

Paradygmaty programowania

Java EE produkcja oprogramowania

Kierunek i poziom studiów: Matematyka, studia I stopnia (licencjackie), rok I

SYLABUS DOTYCZY CYKLU KSZTAŁCENIA Realizacja w roku akademickim 2016/17

Wykład 1_2 Algorytmy sortowania tablic Sortowanie bąbelkowe

Podyplomowe Studium Programowania i Systemów Baz Danych

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

KARTA KURSU. Wstęp do programowania

Analiza algorytmów zadania podstawowe

Sylabus modułu: Matematyczne podstawy informatyki (kod modułu:03-mo2n-12-mpln)

koordynator modułu dr hab. Michał Baczyński rok akademicki 2012/2013

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Technologie informacyjne - wykład 12 -

Informatyka 1. Złożoność obliczeniowa

EGZAMIN - Wersja A. ALGORYTMY I STRUKTURY DANYCH Lisek89 opracowanie kartki od Pani dr E. Koszelew

Programowanie proceduralne INP001210WL rok akademicki 2017/18 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Struktury danych i złozoność obliczeniowa. Prof. dr hab. inż. Jan Magott

INFORMATYKA SORTOWANIE DANYCH.

Rekurencja. Przygotowała: Agnieszka Reiter

Język C, tablice i funkcje (laboratorium, EE1-DI)

Język programowania PASCAL

Programowanie w Javie Lista nr 1. Wybieramy kategorię Java, a wśród Projektów Java Application i [NEXT]

Sortowanie przez wstawianie

Algorytmy i Struktury Danych.

Programowanie komputerów

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie w VB Proste algorytmy sortowania

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to

Podyplomowe Studium Informatyki

WYŻSZA SZKOŁA INFORMATYKI STOSOWANEJ I ZARZĄDZANIA

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

Szczegółowy program kursów szkoły programowania Halpress

Języki programowania zasady ich tworzenia

5. Podstawowe algorytmy i ich cechy.

Algorytm. a programowanie -

Zapisywanie algorytmów w języku programowania

12. Rekurencja. UWAGA Trzeba bardzo dokładnie ustalić <warunek>, żeby mieć pewność, że ciąg wywołań się zakończy.

Algorytmy z powrotami. Algorytm minimax

Przeglad podstawowych pojęć (3) Podstawy informatyki (3) dr inż. Sebastian Pluta. Instytut Informatyki Teoretycznej i Stosowanej

Algorytm i złożoność obliczeniowa algorytmu

KARTA MODUŁU KSZTAŁCENIA

Podstawy programowania Laboratorium. Ćwiczenie 2 Programowanie strukturalne podstawowe rodzaje instrukcji

Szablony funkcji i szablony klas

Podstawy programowania obiektowego

Podstawy programowania. Podstawy C# Przykłady algorytmów

Porównanie czasów działania algorytmów sortowania przez wstawianie i scalanie

Elektrotechnika I stopień (I stopień / II stopień) Ogólnoakademicki (ogólno akademicki / praktyczny) Niestacjonarne (stacjonarne / niestacjonarne)

Rekurencja (rekursja)

Rozwiązanie. #include <cstdlib> #include <iostream> using namespace std;

funkcje rekurencyjne Wykład 12. Podstawy programowania (język C) Funkcje rekurencyjne (1) Funkcje rekurencyjne (2)

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

WYKŁAD 8. Funkcje i algorytmy rekurencyjne Proste przykłady. Programy: c3_1.c..., c3_6.c. Tomasz Zieliński

Transkrypt:

Pojęcia podstawowe. Złożonośd czasowa algorytmów. Rekurencja Algorytmy i struktury danych Wykład 1. Rok akademicki: 2010/2011 Ramowy plan wykładów Pojęcie podstawowe. Poprawnośd i złożonośd algorytmów Rekurencja Algorytmy tablicowe Zbiory Tablice asocjacyjne Struktury listowe Drzewa Grafy 2 1

Literatura Cormen T., Leiserson C., Rivest R., Stein C., Wprowadzenie do algorytmów, Wydawnictwo Naukowo-Techniczne, 2004 Lafore R., Java. Algorytmy i struktury danych, Helion, 2004 Koffman E., Wolfgang P., Struktury danych i techniki obiektowe na przykładzie Javy 5.0, Helion, 2006 Wirth N., Algorytmy + struktury danych = programy, dowolne wydanie Sysło M., Algorytmy, Wydawnictwo Szkolne i Pedagogiczne, Warszawa, 1997 3 Informacje organizacyjne Wymiar godzinowy: 30 + 30 Terminy zajęd: sroda, 13.05, s. 441 Budynek BG Egzamin: pisemny (nie ma zwolnieo z egzaminu) Materiały do wykładu: http://www.uek.krakow.pl/~lulap 4 2

Algorytm sposób postępowania umożliwiający rozwiązanie zadania określonego typu podany w postaci zestawu kolejnych czynności do wykonania wykonawcą algorytmu może byd człowiek lub urządzenie (np. komputer) 5 Struktura danych Zestaw powiązanych ze sobą danych wraz z mechanizmami określającymi sposób tworzenia, likwidowania i wykorzystania zdefiniowanego zestawu jako całości oraz poszczególnych jego elementów. 6 3

Program komputerowy zrozumiały dla komputera sposób zapisu algorytmu i opisu struktur danych zapisywany przy użyciu języków programowania. 7 Ewolucja metod programowania (1) Programowanie w języku maszynowym Programista posługuje się pojęciami charakterystycznymi dla systemu komputerowego, a nie dla dziedziny zastosowao (operuje rozkazami wchodzącymi w skład listy rozkazów procesora) Rozkazy składające się na program programista zapisu w postaci binarnych kodów Programista operuje bezpośrednio na komórkach pamięci operacyjnej. Odpowiedzialny jest za określenie sposobu binarnej reprezentacji informacji. 8 4

Ewolucja metod programowania (2) Programowanie w języku symbolicznym (asemblerze) Programista posługuje się rozkazami pochodzącymi z listy rozkazów procesora (ale są one zapisywane w postaci instrukcji, a nie w postaci binarnych kodów). Języki symboliczne wprowadziły zmiany w sposobie notacji programu, ale nie spowodowały zasadniczych zmian w zestawie pojęd wykorzystywanych do opisu algorytmów. Pojawiła się możliwośd przypisywania nazw komórkom pamięci (definiowanie zmiennych) 9 Ewolucja metod programowania (3) Programowanie w językach wysokiego poziomu I generacji Pojawiła się możliwośd stosowania instrukcji: podstawienia (przypisania), warunkowej, pętli (iteracji), skoku. Przy opisie algorytmy następuje rezygnacja ze stosowania rozkazów z listy rozkazów procesora i pojawia się możliwośd stosowania pojęd o znacznie większym stopniu ogólności. Wprowadzenie mechanizmu deklarowania zmiennych Ułatwione zostało operowanie na wartościach tekstowych Pojawiła się możliwośd korzystania ze złożonych typów danych (tablice, pliki) 10 5

Ewolucja metod programowania (4) Programowanie proceduralne Możliwośd definiowania podprogramów. Zdefiniowanie nowego podprogramu pozwala na rozszerzenie zbioru instrukcji dostępnych w stosowanym języku programowania. Mechanizm parametrów zwiększył uniwersalnośd definiowanych instrukcji. Pojawiła się możliwośd definiowania danych lokalnych (dostępnych tylko w podprogramie) oraz danych globalnych (dostępnych w całym programie) 11 Ewolucja metod programowania (5) Programowanie strukturalne Zwiększenie liczby instrukcji sterujących (np.: różne postaci pętli, instrukcji warunkowych, wyboru, podstawienia) dzięki czemu można było wyeliminowad instrukcję skoku bezwarunkowego Podział programu na dwie części: opis struktur danych i opis algorytmu Zwiększenie liczby dostępnych typów danych (tablice, rekordy, zbiory, pliki), Możliwośd stosowania dynamicznych struktur danych (stos, kolejka, listy, drzewa), Możliwośd definiowania własnych struktur danych. 12 6

Ewolucja metod programowania (6) Programowanie obiektowe Równoległe definiowanie algorytmów i struktur danych i ich połączenie w jedną całośd (klasę): reprezentuje w programie fragment rzeczywistości (jego cechy, jego zachowania), pozwala programiście posługiwad się pojęciami charakterystycznymi dla dziedziny problemu (oderwad się od pojęd związanych ze sprzętem komputerowym), pozwala ukryd szczegóły implementacji klasa abstrakcyjny typ danych (ABSTRAHOWANIE - operacja myślowa polegająca na uwzględnianiu tylko wybranych cech sytuacji (przedmiotu, osoby), z pominięciem cech uznanych za nieistotne) 13 Wymagania wobec algorytmów poprawnośd algorytm generuje prawidłowe rezultaty (nie zawiera błędów), wydajnośd realizacja algorytmu wymaga użycia akceptowalnej ilości zasobów: czasu, pamięci. 14 7

Pojęcie błędu niezgodnośd z obowiązującymi regułami pisania, liczenia, wymowy itp.; odstępstwo od normy; pomyłka postępek, działanie, które przynosi komuś złe skutki; niewłaściwe posunięcie, przedsięwzięcie mylne, fałszywe mniemanie o czymś (przestarz.) Źródło: Słownik języka polskiego PWN 15 Błędy w programowaniu błędy logiczne na etapie projektowania algorytmu (środki zaradcze: stosowanie sprawdzonych algorytmów, formalne dowodzenie poprawności algorytmu, testowanie programu) błędy wykonania programu ujawniające się w trakcie realizacji algorytmu zapisanego w postaci programu (ujawniające się w postaci wyjątków) błędy syntaktyczne polegające na niezgodności tekstu programu z gramatyką języka programowania (wykrywane przez kompilator) 16 8

Złożonośd obliczeniowa Złożonośd obliczeniowa algorytmu ilośd zasobów systemu komputerowego niezbędnych do jego realizacji. Zasoby systemu komputerowego niezbędne do realizacji algorytmu: czas pracy procesora (złożonośd czasowa algorytmu), pamięd operacyjna (złożonośd pamięciowa algorytmu). Złożonośd obliczeniowa jest uzależniona od wielkości zadania. 17 Sortowania przez wybieranie (1) import java.io.*; public class SortowaniePrzezWybieranie { static void sortuj(int [] liczby) { int k, pomoc; for (int i = 0; i < liczby.length - 1; i++) { k = i; for (int j = i; j < liczby.length; j++) if (liczby[k] > liczby[j]) k = j; pomoc = liczby[i]; liczby[i] = liczby[k]; liczby[k] = pomoc; 18 9

Sortowania przez wybieranie (2) static int czytajliczbe() throws IOException { BufferedReader klaw = new BufferedReader (new InputStreamReader (System.in)); return Integer.parseInt(klaw.readLine()); static void drukujwektor(int [] tab) { for (int i = 0; i < tab.length; i++) System.out.print(tab[i] + " "); System.out.print("\n"); 19 Sortowania przez wybieranie (3) public static void main(string [] args) throws IOException { System.out.print("Liczba elementow w wektorze: "); int n = czytajliczbe(); int [] wektor = new int[n]; for (int i = 0; i < wektor.length; i++) wektor[i] = (int) (100 * Math.random()); long czas1, czas2; czas1 = System.currentTimeMillis(); // czas w milisekundach, jaki upłynął od // 1 stycznia 1970 roku, godz. 0:00 sortuj(wektor); czas2 = System.currentTimeMillis(); System.out.println("Czas realizacji obliczen: " + (czas2 - czas1)); 20 10

Sortowania przez wybieranie (4) Rezultat działania programu: Liczba elementow w wektorze: 10000 Czas realizacji obliczen: 250 21 Czas realizacji algorytmu (1) 22 11

Czas realizacji algorytmu (2) Czas (milisekundy) 120000 100000 80000 60000 40000 20000 0 0 50000 100000 150000 200000 250000 y = 0,000002 n 2 0,0094 n + 286,41 23 Oszacowanie czasu realizacji algorytmu (1) 24 12

Oszacowanie czasu realizacji algorytmu (2) Analiza powyższych danych pozwala stwierdzid, że czas obliczeo uzależniony jest przede wszystkim od składnika: 0,000002 n 2 Składnik ten nazywany jest składnikiem dominującym. Po pominięciu stałych współczynników można stwierdzid, że zależnośd pomiędzy czasem wykonania a wielkością zadania ma charakter funkcji kwadratowej. Kwadratowy charakter zależności uwidacznia się w coraz większym stopniu wraz ze wzrostem wielkości zadania. 25 Cechy empirycznego określania złożoności Zalety: otrzymane czasy obliczeo są proste w interpretacji Wady: koniecznośd wielokrotnego uruchamiania programu (dla złożonych algorytmów może to byd bardzo czasochłonne), uzyskane wyniki dotyczą zastosowanego w obliczeniach zestawu danych (trudno jest określid czas realizacji dla przypadku najlepszego, najgorszego oraz przeciętnego ), wyniki dotyczą zwykle stosunkowo niewielkich zbiorów danych nie wiadomo, czy dla zbiorów o większym rozmiarze charakter zależności się nie zmieni, czas jest uzależniony od szybkości i architektury komputera, języka programowanie, techniki translacji, systemu operacyjnego trudna porównywalnośd wyników z uwagi na wielozadaniowy charakter systemów operacyjnych trudno jest określid, jaka częśd czasu była rzeczywiście przeznaczona na realizację analizowanego programu. 26 13

Bezpośrednia analiza algorytmów Analiza dotyczy: charakteru zależności (np. zależnośd liniowa lub kwadratowa), a nie jej dokładnej postaci (wzór funkcji) uwzględniany jest element dominujący, pomijane są współczynniki stałe górnego i dolnego ograniczenia czasu realizacji algorytmu (a nie czasu realizacji algorytmu) górne ograniczenie czas realizacji algorytmu jest nie większy niż... (ale może byd krótszy) przypadek pesymistyczny, dolne ograniczenie czas realizacji algorytmu jest nie mniejszy niż... (ale może byd dłuższy) przypadek optymistyczny, zachowania się algorytmu dla zbiorów danych o dużej wielkości (czyli dla wszystkich n większych od pewnej wartości n 0 ) 27 Górne ograniczenie czasu realizacji algorytmu (1) f(n) czas realizacji algorytmu (zależny od n) f(n) zależy od wielu czynników i podanie dokładnego charakteru zależności jest trudne łatwiej jest zdefiniowad ograniczenie górne dla f(n). c g(n) f(n) n 28 14

Górne ograniczenie czasu realizacji algorytmu (2) Czas realizacji algorytmu jest rzędu co najwyżej g(n), jeśli istnieją stała rzeczywista c > 0 i stała naturalna n 0 takie, że nierównośd f(n) c g(n) zachodzi dla każdego n n 0. Zbiór wszystkich funkcji f(n) spełniających powyższe ograniczenie określany jest jako O(g(n)). O(g(n)) = {f(n): istnieją dodatnie stałe c oraz n 0 takie, że 0 f(n) c g(n) dla wszystkich n n 0 29 Górne ograniczenie czasu realizacji algorytmu (3) Stwierdzenie: czas realizacji algorytmu wynosi O(g(n)) lub czas realizacji algorytmu jest rzędu co najwyżej g(n) lub algorytm jest klasy O(g(n)) oznacza: że istnieje taka stała c, że dla n n 0 czas realizacji algorytmu wynosi co najwyżej c g(n). 30 15

Dolne ograniczenie czasu realizacji algorytmu (4) Czas realizacji algorytmu jest rzędu co najmniej g(n), jeśli istnieją stała rzeczywista c > 0 i stała naturalna n 0 takie, że nierównośd f(n) c g(n) zachodzi dla każdego n n 0. Zbiór wszystkich funkcji spełniających to ograniczenie określany jest jako Ω(g(n)) Ω(g(n)) = {f(n): istnieją dodatnie stałe c i n 0 takie, że 0 cg(n) f(n) dla wszystkich n n 0 f(n) c g(n) n 31 Dolne i górne ograniczenie czasu realizacji algorytmu (1) Czas realizacji algorytmu jest dokładnie rzędu g(n) jeśli istnieją stała rzeczywista c 1 > 0, c 2 > 0 i stała naturalna n 0 takie, że nierównośd c 1 g(n) f(n) c 2 g(n) zachodzi dla każdego n n 0. c 2 g(n) f(n) c 1 g(n) n 32 16

Dolne i górne ograniczenie czasu realizacji algorytmu (2) Zbiór wszystkich funkcji spełniających to ograniczenie określany jest jako Θ(g(n)) Θ(g(n)) = {f(n); istnieją dodatnie stałe c 1, c 2 i n 0 takie, że 0 c 1 g(n) f(n) c 2 g(n) dla wszystkich n n 0 33 Średnia złożonośd obliczeniowa Średnia złożonośd czasowa uwzględnia prawdopodobieostwa pojawienia się każdego możliwego zestawu danych wejściowych Z i (n) i-ty możliwy zestaw danych n-elementowy p i prawdopodobieostwo wystąpienia i-tego zestawu T i (n) złożonośd czasowa algorytmu dla i-tego zestawu danych Średnia złożonośd czasowa algorytmu dana jest formułą: T śr n i p T i i n 34 17

Złożonośd obliczenia sortowania przez wybieranie (1) static void sortuj(int [] liczby) { int k, pomoc; for (int i = 0; i < liczby.length - 1; i++) { //koszt K1 k = i; for (int j = i; j < liczby.length; j++) //koszt K2 if (liczby[k] > liczby[j]) k = j; //koszt K3 pomoc = liczby[i]; liczby[i] = liczby[k]; liczby[k] = pomoc; 35 Złożonośd obliczenia sortowania przez wybieranie (2) for (int i = 0; i < n - 1; i++) { K1 for (int j = i; j < n; j++) { K2 K3 36 18

Złożonośd obliczenia sortowania przez wybieranie (3) for (int i = 0; i < n - 1; i++) { K1 (n 1) * K2 K3 37 Złożonośd obliczenia sortowania przez wybieranie (4) (n 1) * K1 + (n 1) [n * K2 + (n-1) * K2 +... + 2 * K2] + (n 1) * K3 = = n * K1 K1 + *½ * (2 + n) * (n 1) * K2] + n * K3 K3 = = n * K1 K1 + n * K2 K2 + ½ * n 2 * K2 ½ * n * K2 + n * K3 K3 = = ½ * K2 * n 2 + (K1 + ½ * K2 + K3) * n (K1 + K2 + K3) = O(n 2 ) 38 19

Rodzaje złożoności (1) Złożoność logarytmiczna log n W każdym kroku algorytmu zadanie o rozmiarze n jest sprowadzane do zadania o rozmiarze n / 2 Przykład: algorytm wyszukiwania binarnego jest klasy O(log n) Przykładowa realizacja wyszukiwania binarnego: Mamy odszukad wartośd 11 w ciągu liczb: 1, 2, 7, 9, 9, 11, 12, 15, 22, 34, 52, 67, 87, 90, 99 1, 2, 7, 9, 9, 11, 12 9, 11, 12 39 Rodzaje złożoności (2) Złożoność liniowa n gdy dla każdego elementu pochodzącego z n elementowego zbioru danych wykonywana jest stała liczba operacji Przykłady: wyszukiwanie sekwencyjne sumowanie liczb w wektorze wyznaczanie minimum, maksimum 40 20

Rodzaje złożoności (3) złożoność liniowo logarytmiczna n log n gdy w każdym kroku zadanie o rozmiarze n jest sprowadzane do dwóch zadao o rozmiarze n/2, a uzyskane wyniki są ponownie scalane Przykład: sortowanie przez łączenie jest klasy O(n log n) sortowanie szybkie jest klasy O(n 2 ), ale przeciętny czas realizacji algorytmu jest rzędu n log n 41 Rodzaje złożoności (4) złożoność kwadratowa n 2 gdy dla każdej pary elementów realizowana jest pewna, stała liczba operacji (zwykle algorytmy takie są zapisywane za pomocą dwóch zagnieżdżonych pętli for) Przykłady: proste metody sortowania (przez wstawianie, wybieranie, bąbelkowe) są klasy O(n 2 ), również średni czas realizacji tych metod jest rzędu O(n 2 ) 42 21

Rodzaje złożoności (5) złożoność wielomianowa stopnia wyższego niż dwa (n 3, n 4,...) Przykład: mnożenie macierzy w sposób tradycyjny jest algorytmem klasy O(n 3 ) 43 Rodzaje złożoności (6) Złożoność wykładnicza postaci 2 n gdy realizowanych jest n kroków, a liczba operacji w każdym z nich wzrasta w sposób geometryczny Przykład: wieże Hanoi 44 22

Rodzaje złożoności (7) Złożoność wykładnicza typu n! gdy pewna, stała liczba operacji realizowana jest dla każdej permutacji n elementów Przykład: Tworzenie magicznych kwadratów z n elementów (pierwiastek z n musi byd wartością całkowitą) Algorytm postępowania: tworzymy kolejną permutację, wpisujemy do kwadratu i sprawdzamy, czy spełnia konieczne warunki. 45 Rodzaje złożoności (8) 46 23

Rekurencja Rekurencyjny sposób zapisu kodu programu - z poziomu podprogramu wywoływany jest ten sam podprogram. 47 Przykład (1) public class Rekurencja01 { static void f() { System.out.println("Poczatek"); f(); System.out.println("Koniec"); public static void main(string [] args) { f(); 48 24

Przykład (2) main() { f() Początek f(x) Koniec Początek f(x) Koniec Początek f(x) Koniec Początek f(x) Koniec i.t.d. 49 Przykład (3) Efekt uruchomienia programu: Poczatek Poczatek Poczatek... Poczatek Exception in thread "main" java.lang.stackoverflowerror 50 25

Warunek stopu Wywołania rekurencyjne muszą się zakooczyd (w podprogramie musi zostad zdefiniowany warunek zatrzymania się algorytmu /warunek stopu/). 51 Przykład (1) public class Rekurencja02 { static int licznik = 0; static void f() { licznik++; System.out.println("Poczatek"); if (licznik <=5) f(); System.out.println("Koniec"); public static void main(string [] args) { f(); 52 26

Przykład (2) main() { f() licznik = 1 Początek f(x) Koniec licznik = 2 Początek f(x) Koniec licznik = 3 Początek f(x) Koniec licznik = 4 Początek f(x) Koniec licznik = 5 Początek f(x) Koniec licznik = 6 Początek Koniec 53 Przykład (3) Efekt uruchomienia programu: Poczatek Poczatek Poczatek Poczatek Poczatek Poczatek Koniec Koniec Koniec Koniec Koniec Koniec 54 27

Rekurencyjne obliczanie silni (1) public class Rekurencja03 { static int silnia(int n) { int pomoc; System.out.println("Wywolanie: silnia(" + n + ")"); if ((n == 0) (n == 1)) pomoc = 1; else pomoc = n * silnia(n-1); System.out.println("Zwrocenie wyniku: " + n + "! = " + pomoc); return pomoc; public static void main(string [] args) { System.out.println("4! = " + silnia(4)); 55 Rekurencyjne obliczanie silni (2) 56 28

Rekurencja może byd kosztowna... public class Rekurencja04 { static int licznik = 0; static int fib(int n) //obliczanie n-tej liczby Fibonacciego { licznik++; if (n == 0) return 0; else if (n == 1) return 1; else return fib(n-1) + fib(n-2); public static void main(string [] args) { System.out.println("5-ta liczba Fibonacciego to: " + fib(5)); System.out.println("Liczba wywolan funkcji:" + licznik); 57 Efekt działania: 5-ta liczba Fibonacciego to: 5 Liczba wywolan funkcji: 15 58 29

Sposób wyznaczania liczb Fibonacciego Jeśli istnieje oczywiste rozwiązanie iteracyjne, to należy je wybrad. 59 Sterowanie kolejnością wykonywania działao (1) public class Rekurencja05 { static void sekwencja(int n) { System.out.print(n + " "); if (n > 0) sekwencja(n-1); public static void main(string [] args) { sekwencja(5); System.out.println(); Efekt działania programu: 5 4 3 2 1 0 60 30

Sterowanie kolejnością wykonywania działao (2) public class Rekurencja06 { static void sekwencja(int n) { if (n > 0) sekwencja(n-1); System.out.print(n + " "); public static void main(string [] args) { sekwencja(5); System.out.println(); Efekt działania programu 0 1 2 3 4 5 61 Wieże Hanoi public class Rekurencja08 { static void przesun(int ile, char wiezazrodlowa, char wiezadocelowa, char wiezapomocnicza) { if (ile == 1) System.out.println(wiezaZrodlowa + " => " + wiezadocelowa); else { przesun(ile-1,wiezazrodlowa,wiezapomocnicza, wiezadocelowa); System.out.println(wiezaZrodlowa + " => " + wiezadocelowa); przesun(ile-1,wiezapomocnicza,wiezadocelowa, wiezazrodlowa); 62 31

Złożonośd algorytmu: Wieże Hanoi (1) Analizowana jest liczba przesunięd potrzebna do rozwiązania zadania z n krążkami (liczbę przesunięd oznaczymy przez P(n)) gdy n = 1 to P(1) = 1 gdy n > 1 to P(n) = 2 * P(n 1) + 1 63 Złożonośd algorytmu: Wieże Hanoi (2) Poziom 0 P(n) Liczba przesunięć 1 P(n-1) 1 P(n-1) 1 2 P(n-2) 1 P(n-2) P(n-2) 1 P(n-2) 2 3 P(n-3) 1 P(n-3) P(n-3) 1 P(n-3) P(n-3) 1 P(n-3) P(n-3) 1 P(n-3) 4 64 32

Złożonośd algorytmu: Wieże Hanoi (3) P(n) = P1 + P2 + P3 +... + Pn = 2 n 1 W powyższym wzorze zastosowany został wzór na sumę n pierwszych elementów ciągu geometrycznego (o elementach b 1, b 2,..., bn i ilorazie q) S n = b 1 * (q n 1) / (q 1) 65 Inwersja elementów w wektorze (1) public class Rekurencja07 { static void wyswietlwektor(int [] w) { for(int i = 0; i < w.length; i++) System.out.print(w[i] + " "); System.out.println(); 66 33

Inwersja elementów w wektorze (2) static void inwersja(int poczatek, int koniec, int [] w) { if (poczatek < koniec) { int pomoc = w[poczatek]; w[poczatek] = w[koniec]; w[koniec] = pomoc; inwersja(poczatek+1,koniec-1,w); 67 Inwersja elementów w wektorze (3) public static void main(string [] args) { int [] tab = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; wyswietlwektor(tab); inwersja(0,tab.length-1,tab); wyswietlwektor(tab); Efekt działania programu: 1 2 3 4 5 6 7 8 9 10 11 11 10 9 8 7 6 5 4 3 2 1 68 34

Sortowanie szybkie (1) Hoare, 1960 void quicksort(int tab[], int first, int last) wybierz jedną z wartości znajdujących się w wektorze (w poniższym algorytmie wybierana jest wartośd znajdująca się na pozycji o numerze first) dokonaj przemieszczenia elementów w wektorze, tak aby uzyskad: elementy < x x elementy >= x za pomocą tej samej procedury uporządkuj częśd wektora znajdującą się na lewo od wartości x oraz częśd znajdującą się na prawo od wartości x. średnia złożonośd obliczeniowa: O(n * log(n)) pesymistyczna złożonośd obliczeniowa O(n 2 ) 69 Sortowanie szybkie (2) public class QuickSort { public static void swap (int tab[], int x, int y) { int temp = tab[x]; tab[x] = tab[y]; tab[y] = temp; 70 35

Sortowanie szybkie (3) public static int partition(int tab[], int first, int last) { int pivot = tab[first]; int up = first; int down = last; do { while ((up < last) && (pivot >= tab[up])) up++; while (pivot < tab[down]) down--; if (up < down) swap(tab,up,down); while (up < down); swap(tab,first,down); return down; 71 Sortowanie szybkie (4) public static void quicksort(int tab[], int first, int last) { if (first >= last) return; int pivot = partition(tab, first, last); quicksort(tab, first, pivot-1); quicksort(tab, pivot+1, last); 72 36

Sortowanie szybkie (5) public static void main(string argv[]) { int n = 10; int tab[] = new int[n]; for (int i=0 ; i < n; i++) tab[i] = (int) (100 * Math.random()); quicksort(tab, 0, n-1); for (int i=0 ; i < n; i++) System.out.print(tab[i] + " "); System.out.println(); 73 Sortowanie przez łączenie Mergesort (1) sort(int poczatek, int koniec, int [] w), podziel wektory na dwie połowy, posortuj każdą z nich (za pomocą tej samej metody, o ile ich długośd > 1), połącz posortowane części w całośd, złożonośd obliczeniowa: O(n * log(n)). 74 37

Sortowanie przez łączenie Mergesort (2) public class MergeSort { static void wyswietlwektor(int [] w) { for(int i = 0; i < w.length; i++) System.out.print(w[i] + " "); System.out.println(); 75 Sortowanie przez łączenie Mergesort (3) static void sort(int poczatek, int koniec, int [] w) { if (poczatek >= koniec) return; int srodek = (poczatek + koniec) / 2; sort(poczatek, srodek, w); sort(srodek+1, koniec, w); scal(poczatek, srodek, koniec, w); 76 38

Sortowanie przez łączenie Mergesort (3) static void scal(int poczatek, int srodek, int koniec, int [] w) { int pocz1 = poczatek; int kon1 = srodek; int pocz2 = srodek + 1; int kon2 = koniec; while ((pocz1 <= kon1) && (pocz2 <= kon2)) { if (w[pocz1] < w[pocz2]) pocz1++; else { int pomoc = w[pocz2]; for (int i = pocz2-1; i >= pocz1; i--) w[i+1] = w[i]; w[pocz1] = pomoc; pocz1++; kon1++; pocz2++; 77 Sortowanie przez łączenie Mergesort (4) public static void main(string [] args) { int [] tab = {1, 5, 3, 7, 7, 9, 2, 3, 2, 2, 3; wyswietlwektor(tab); sort(0,tab.length-1,tab); wyswietlwektor(tab); Wynik działania programu 1 5 3 7 7 9 2 3 2 2 3 1 2 2 2 3 3 3 5 7 7 9 78 39