Przy pomocy indukcji udowodnimy, że nastąpi koniec świata, a warto byłoby wiedzieć kiedy, czy przed czy po egzaminie.

Wielkość: px
Rozpocząć pokaz od strony:

Download "Przy pomocy indukcji udowodnimy, że nastąpi koniec świata, a warto byłoby wiedzieć kiedy, czy przed czy po egzaminie."

Transkrypt

1 POPRAWNOŚĆ ALGORYTMÓW W momencie gdy mikrofon został Panu w ręce a nie powinien i tekst O ktoś to urwał. Jak ktoś wygra światowy konkurs, to mu nawet 3 postawie na koniec bez egzaminu Do Francji możecie sobie sami pojechać, a do Korei fajnie gdyby Was ktoś wysłał. - Poprawność algorytmów - podstawy matematyczne: - przyrost funkcji i notacje asymptotyczne - sumowanie szeregów (kryteria zbieżności szeregów się też przydają) - indukcja matematyczna (bo chodzi o dowodzenie twierdzeń opartych na liczbach naturalnych) Przy pomocy indukcji udowodnimy, że nastąpi koniec świata, a warto byłoby wiedzieć kiedy, czy przed czy po egzaminie. Będziemy omijać dowody poprawności algorytmów, my tylko powiemy jak to się robi. Algorytm jest poprawny, jeśli dla każdego legalnego wejścia kończy swoje działanie i tworzy pożądany wynik. Automatyczne dowiedzenie poprawności nie jest możliwe. Do tego nie ma za bardzo standardowych metod robienia tego, nie ma tak, że zawsze dołożymy jedną z technik i pójdzie dobrze, jest troszkę schematów, ale myśleć nadal trzeba. Istnieją jednak techniki i formalizmy pozwalające na dowodzenie poprawności algorytmów. Poprawność praktyczna i całkowita (teoretyczna) Poprawność praktyczna JEŚLI punkt wynikowy(pomiędzy algorytmem i wynikiem, to przejście) został osiągnięty, to otrzymaliśmy poprawny wynik, czasami nam to wystarcza a chcielibyśmy, mieć poprawność całkowitą czyli jeśli otrzymamy wynik to będzie on poprawny i czasami nam to wystarcza. ZAWSZE ten punkt wynikowy zostanie osiągnięty i otrzymamy poprawny wynik. DOWODZENIE - w celu dowiedzenia poprawności algorytmu wiążemy ze specyficznymi miejscami algorytmu stwierdzenia (dotyczące stanu wykonania) np. A[1], A[k] są posortowane niemalejąco - warunki [początkowe stwierdzenia których prawdziwość zakładamy przed wykonaniem algorytmu (Input) - warunki końcowe stwierdzenia, które muszą być prawdziwe PO WYKONANIU algorytmu lub podprogramu (output) Najłatwiej jest dowodzić, gdy algorytm jest sekwencyjny, ale często tak nie jest, bo zwykle mamy do czynienia z nawrotami problemów. Niezmienniki pętli Niezmienniki stwierdzenia prawdziwe za każdym razem kiedy osiągany jest pewien punkt algorytmu (może to zdarzyć się wielokrotnie w czasie wykonania algorytmu) Dla niezmienników pętli należy pokazać: - inicjalizację prawdziwość przed pierwszą iteracją - zachowanie jeśli stwierdzenie jest prawdziwe przed iteracją to pozostaje prawdziwe przed następną iteracją - zakończenie kiedy pętla zakończy działanie niezmiennik daje własność przydatną do wykazania poprawności algorytmu Wykłady z Algorytmów i Struktur Danych 1

2 Rozbija się o to, że zwykle nie wiemy, ile razy się pętla wykona, np. w Algorytmie Euklidesa nie wiemy jak to będzie. Najpierw zawsze sprawdzamy czy nasz warunek jest spełniony i potem po każdym wykonaniu znów patrzę czy założenie jest prawdziwe i potem posługujemy się implikacją, że jeśli założenie jest prawdziwe dla n przejść to jest prawdziwe dla n+1. Zwykle stan na zakończenie niezmiennika, to jest nasz dowód typu że to co nasz algorytm obrabia jest faktycznie tym co miało być, dostaniemy wynik, który mówi nam o poprawności danych. Przykład poszukiwanie binarne, poszukiwanie przez połowienie z poprzedniego wykładu. - chcemy mieć pewność, że jeżeli zwracany jest N IL to wartości q nie ma w tablicy A - niezmiennik: na początku każ Ego wykonania pętli Chile A[i]<q dla każdego i należącego [1..left-1] raz A[i]>q dla każdego i należącego do [right+1,n]. - inicjalizacja: left=1, right=n niezmiennik jest prawdziwy, bo nie ma elementów w [1..left-1] i [rignt+1..n] (nie ma takich jednocześnie i tu i tu) Algorytm wyglądał tak: Left:=1 right :=n Do J:= podłoga z (left+wright)/2 If A[j]=q then return j Else if A[j]>q then right:=j-1 Else left=j+1 While left<=right Return NIL Poszukiwanie binarne 2 (drugie rozważania, ale ten sam algorytm co wyżej) Zachowanie: jeśli A[j]>q to A[i]>q dla wszystkich i z przedziału [j..n], ponieważ tablica jest posortowana. Wtedy przypisano j-1 do right. Stąd druga część niezmiennika również zachodzi,. Analogicznie pokazuje się pierwszą część. Czyli widzimy że tu przechodniość relacji porządku jest istotna. Poszukiwanie binarne (3) Zakończenie 0- kiedy pętla kończy działanie, mamy left > right. Niezmiennik oznacza, że q jest mniejsze od wszystkich elementów A na lewo od left oraz większy od wszystkich elementów A na prawo od right. To wyczerpuje wszystkie elementy A. W ten oto sposób pokazaliśmy, że nasz algorytm jest poprawny, Nasze założeniem to było to, że dane są posortowane i to było wykorzystane podczas pokazania przejścia (w trakcie pokazania zachowania niezmiennika, tego że metoda możę być przyłożona do tych danych i że jest ona istotna). Przykład sortowanie przez wstawianie (było na poprzednim wykładzie) For j=2 to length(a) Do key:=a[j] I:=j-1 While i>0 and A[i]>key Do A[i+1]:A[i] i- - A[I+1]:=key Niezmiennik na początku każdego wykonania pętli for A[1..j-1] składa się z posortowanych elementów Inicjalizacja j=2, niezmiennik jest trywialny, A[1] jest zawsze posortowana (nie da się źle ułożyć mając tablicę tylko z jednym elementem) Wykłady z Algorytmów i Struktur Danych 2

3 Zachowanie: wewnątrz pętli Chile przestawia się elementy A[j-1], A[j-2],,A[j-k] o jedną pozycję bez zmiany ich kolejności. Element A[j] jest wstawiany na k-tą pozycję tak, że A[k-1]<=A[k]<=A[k+1]. Stąd A[1..j-1] jest posortowane Zakończenie kiedy pętla się kończy (j=n+1) niezmiennik oznacza, ze cała tablica została posortowana. Czyli dowiedliśmy poprawności algorytmu posługując się jednym niezmiennikiem dla jednej pętli. Notacje asymptotyczne Cel: Upraszczanie analizy czasu wykonania, zaniedbywanie szczegółów które mogą wynikać ze specyficznej implementacji czy sprzętu - zaokrąglanie dla liczb w przybliżeniu jest równe zaokrąglanie dla funkcji 3n^2 w przybliżeniu jest równe n^2 Główna idea: Jak zwiększa się czas wykonania algorytmu wraz ze wzrostem rozmiaru wejścia (w granicy) - Algorytm asymptotycznie lepszy będzie bardziej efektywny dla prawie wszystkich rozmiarów wejść (z wyjątkiem być może małych ). Np. gdy wiemy że coś jest dodatnie to zaniedbujemy moduł gdy mówimy o czasie, bo wiadomo, że nie rozważamy ujemnych czasów itp. Czyli w funkcjach próbujemy znaleźć wszystko to co jest istotne dla ich wzrostu, jak szybko rośnie skala złożoności algorytmu, gdy funkcje są tej samej klasy to je zwykle utożsamiamy ze sobą. Sens notacji asymptotycznych jest taki, byśmy umieli porównać złożoność danych algorytmów. Np. jak mamy jakieś wielomiany to porównujemy tylko to co jest przy najwyższej potędze, bo wszytsko inne za wolno rośnie, pamiętajmy tylko, że to wszystko mam iejsce dla dużej ilości danych, wtedy się to sprawdza, bo dla małej ilośći danych może być już różnie. Notacja O (duże O) - asymptotyczne ograniczenie górne (to będzie na matematyce dyskretnej) - f(n) = O(g(n)), jeżeli istnieje stała c i n_0 takie, że f(n)<=c g(n) dla n>=n_0 (czyli dla prawie wszystkich rozmiarów wejścia n mamy tak, że wykres c razy g(n) jest nad f(n), jest zawsze takim ograniczeniem, czyli czas działania c g(n) jest zawsze większy od czasu działania f(n), takie ograniczenie czasu z góry) - f(n) i g(n) są nieujemnymi funkcjami całkowitymi Korzysta się z niej przy analizie najgorszego przypadku. - Prosta zasada: odrzucamy mniej istotne dla czasu składniki i czynniki stałe np.: 50 n log n jest O(n log n) 7n-3 jest O(n) 8n^2 log n + 5n^2+n jest O(n^2 log n) - O jest ograniczeniem górnym więc np. (50 n log n) jest typu O(n^5), ale interesuje nas najlepsze możliwe oszacowanie, w tym przypadku jest to O(n log n) Notacja Omega (tu symbol dużej omegi) - asymptotyczne ograniczenie dolne - f(n) = omega(g(n)) jeśli istnieje stałą c i n_0 takie, że c g(n)<=f(n) dla n>=n_0 Opisuje najlepsze możliwe zachowanie się algorytmu, czyli bada najlepszy przypadek, którego zwykle nie badany, zwykle nam to nie jest potrzebne. Notacja duże Teta - dokładne oszacowanie asymptotyczne - f(n) = Teta(g(n)) jeżeli istnieją stałe c_1, c_2 i n_0 takie, ze c_1 g(n),=f(n)<=c_2 g(n) dla n>= n0 - f(n) = Teta (g(n)) wtedy i tylko wtedy gdy Wykłady z Algorytmów i Struktur Danych 3

4 Istnieją dwie In ne notacjhe asymptotyczne - małe o f(n) = o(g(n)) i było coś jeszcze Analogie do zależności pomiędzy liczbami: - f(n)=o(g(n)) co jest w przybliżeniu równe f<=g - f(n)=omega(g(n)) w przybliżeniu jest równe f>=g - Teta f=g - O f<g - Małe omega f>g Zwykle zapisujemy f(n)=o(g(n)), co formalnie powinno być rozumiane jako f(n) należy do O(g(n)). Złożoności 400n (liniowa) < 20nlogn < 2n^2 < n^4 < 2^n(wykładnicza) < n! < n^n Dlatego się nad złożonością zastanawiamy, byśmy mogli uzyskać wynik w tym stuleciu a nie w przyszłym, by w ogóle algorytm dla nas miał sens, sama poprawność itp. Nie wystarczy. Algorytm jeszcze musi być do zastosowania. O(1) się wykona zawsze tak samo długo niezależnie od ilości elementów np. znajdź pierwszy element tablicy jest takim zadaniem, bez względu na rozmiar tablicy zawsze tyle samo czasu nam zajmie znalezienie pierwszego elementu. O(n) gdy mam zsumować n elementów tablicy O(1)<O(ln n)<o(n),o(nlogn)<o(n^2) Im większa złożoność tym rzadziej da się algorytm zastosować. Zwykle można coś uzyskać szybciej, lae wszystko ma swojącene. Szereg geometryczny - dana jest liczba całkowita n_0 i rzeczywiste 0<a różne od 1 Suma od i=0 do n a^i = 1+a+a^2+ +a^n = i tu dziwny wzór wcale nie taki normalny z tablic - szereg geometryczny reprezentuje przyrost wykładniczy Szereg arytmetyczny (gdy wykonujemy w jednej pętli drugą pętlę zależną od pierwszego iteratora, wtedy mamy do czynienia z tym szeregiem) Suma od i=0 do n po i = n = n(1+n)/2 - przyrost kwadratowy Przykład dla sumowania, był gdzieś wyżej algorytm a już na pewno na poprzednich zajęciach. Czas działania sortowania przez wstawianie jest zdeterminowany przez zagnieżdżone pętle. Czas wykonania pętli reprezentuje szereg Suma od j=2 do n po (j-1) = O(n^2) czyli otrzymaliśmy złożoność na poziomie kwadratowym, ogólnie przy sortowaniu można uzyskać lepszy wynik niż tu widać. Dowody indukcyjne Indukcji używamy dla zbiorów dobrze uporządkowanych np. dla naturalnych liczb. Chcemy pokazać prawdziwość własności P dla wszystkich liczb całkowitych n>=n0 Założenie indykcje: dowodzimy prawdziwości P dla n0 Krok indukcyjny: dowodzimy, ze z prawdziwości P dla wszystkich k, n0<=k<=n-1 wynika prawdziwość P dla n. Przykład: S(n) = suma po i od i=0 do n = n(n+1)/2 dla n>=1 Założenie indukcyjne S(1)=Suma od i=0 do 1 po i = 1(1+1)/2 Wykłady z Algorytmów i Struktur Danych 4

5 Metoda dziel i zwyciężaj Metoda rozwiązywania problemów, która sprowadza się do tego by się nie namęczyć, a jednocześnie być skutecznym. Czyli duży problem dzielimy na mniejsze części, to jak branie kredytu i spłacanie go w ratach. Czyli rozwiązujemy małe podpproblemy, a potem próbujemy jakoś skleić rozwiązania. Przykładowe problemy (które możemy rozwiązać przy pomocy tej metody) - wypełnianie planszy (np. układanki dla dzieci, to dzielenie na mniejsze problemy nie zawsze jest takie oczywiste) -Poszukiwanie (binarne) (analogia z ksiązką telefoniczną, najpierw dzielimy na pół i porównujemy w której z połówek się znajduje nasz element itp.) - sortowanie (sortowanie przez łączenie merge sort) (np. rozbijamy na zadania, które posortować umiemy a potem problemem największym jest złożenie tych wszystkich rozwiązań), analogiczne jest sortowanie szybkie - problem końca świata Ad wypełnienie planszy Mamy planszę 2^n x 2^n i wypełniamy klocuszkami w kształcie literki L złożonego z trzech elementów,. Gdy zabierzemy jeden klocuszek z planszy, czyli zabraknie jednego pola na niej to ZAWSZE da się wypełnić ją tymi klocuszkami. Pytanie więc oczywiście brzmi jak to zrobić, jak ją wypełnić tymi naszymi klocuszkami, wypełniać planszę po kolei wcale nie jest łatwo, rozwiązanie jest zależne od położenia tego pustego miejsca na planszy. Zastanawiamy się więc jakie zadanie byłoby rozwiązać prościej o tym samym problemie. Zaczynamy więc od planszy 2x2 to jest analogiczny problem, ale umiemy go rozwiązać. Pytanie więc brzmi jak sprowadzić nasz duży problem do tych małych łatwych problemów. Wystarczy więc naszą plansze najpierw pociąć na 4 kawałki takim krzyżykiem, a potem każdy kwadracik dzielimy dalej krzyżykiem itd. Pomysł ten ma ten problem, że jeden z tych kwadratów jaki dostaniemy będzie miał wycięte pole, a pozostałe części, pozostałe trzy kwadraty nie będą miały naszego Pola, ale możemy w środku krzyżyka położyć klocek (kładziemy go tak, ze jego kawałki leżą w tych kwadratach w których NIE ma zabranego pola). W ten sposób mam problem naprawdę podobny do tego jaki był na początku. Zastanawiamy się, czy doszliśmy już do zadania trywialnego czy też nie. Jeśli nie, to dalej postępujemy jak wcześniej. To co klei nasze rozwiązania otrzymane to ten nasz leżący na środku klocuszek. Czyli realizujemy funkcje rekurencyjne Algorytm Input- plansza 2^nx2^n, L pozycja brakującego pola Output wypełniona plansza Tile(n,L) If n=1 then Przypadek trywialny Wypełnij jednym klockiem Return Umieść jeden klocek po środku planszy Podziel plansze na 4 równe części Niech L1, L2,L3,L4 oznaczają pozycje czterech brakujących pól Tile(n-1,L1) Tile(n-1,L2) Tile(n-1,L3) Tile(n-1,L4) Metoda konstrukcji algorytmów dziel i zwyciężaj : - jeśli problem jest na tyle mały, że umiesz go rozwiązać zrób to, jeśli nie to: a) podział podziel problem na dwa lub więcej rozdzielnych podproblemów Wykłady z Algorytmów i Struktur Danych 5

6 b) rozwiązanie wykorzystaj metodę rekurencyjnie dla rozwiania tych podproblemów c) łączenie połącz rozwiązania podproblemów tak, aby rozwiązać oryginalny problem Poszukiwanie binarne Odnaleźć liczbę w posortowanej tablicy - przypadek trywialny tablica jest jednoelementowa - albo dzielimy tablicę na dwie równe części i rozwiązujemy zadanie osobno dla każdej z nich Input A[1..n] posortowana niemalejąco tablica liczb, s- liczba OUTPUT indeks j taki, że A[j]=s NIL jeśli dla każdego j z przedziału [1,n] mamy A[j]różne od s Algorytm Binary serach(a,p,r,s): If p=r then If A[p]=s then return p Else return NIL Q:=podłoga((p+r)/2) Ret:=Binary search(a,p,q,s) IF RET=nil THEN RETURN Binary serch(a,q+1,r,s) Else return ret; Czas działania algorytmu z odwołaniami, rekursywnymi można opisać poprzez rekurencję Równanie, nierówność opisująca funkcję poprzez jej wartość dla mniejszego argumentu Przykład poszukiwanie binarne T(n)= Teta(1) if n=1 lub 2T(n/2)+Teta(1) if n>1 Po rozwiązaniu daje to złożoność O(n)! taką samą jak dla metody naiwnej (czyli sprawdzania po kolei). T(n)=Teta(n) nie lepiej niż dla metody siłowej! Poprawa rozwiązać zadanie tylko dla jednej połowy tablicy Tego nie mam Czyli nie ma jednej 2, która była wyżej T(n)= Teta(1) if n=1 lub T(n/2)+Teta(1) if n>1 T(n)=Teta(lg n)! Metoda sortowania przez wstawianie nie realizuje naszego dzisiejszego problemu. Sortowanie przez łączenie (merge sort) - podziel Jeśli S posiada przynajmniej dwa elementy (1 lub 0 elementów = przypadek trywialny) podziel S na dwie równe (z dokładnością do 1 elementu) części S1 i S2 (tj. S1 zawiera pierwsze sufit (n/2) elementów, a S2 kolejne (podłoga (n/2)) - zwyciężaj posortuj sekwencje S1 i S2 stosując merge sort - połącz połącz elementy z dwóch posortowanych sekwencji S1 i S2 w sekwencję S zachowaniem porządku. Algorytm merge sort Merge Sort (A,p,r) If p<r then Q:=podłoga((p+r)/2) Merge Sort(A,p,q) Wykłady z Algorytmów i Struktur Danych 6

7 Merge Sort(A,q+1,r) Merge(A,p,q,r) Merge(A,p,q,r) wybieramy mniejszy z dwóch elementów na początku sekwencji A[p..q] Oraz A[q+1..r] i wkładamy go do sekwencji wynikowej, przestawiamy odpowiedni znacznik. Powtarzamy to aż do wyczerpania się elementów. Rezultat kopiujemy do A[p..r]. Tu był śmieszny przykład z drzewkiem tak jak na bazach jest na fotach. Ta metoda działa nawet jeśli ciągi są różnej długości, jeden może być krótki a drugi długi. Sortowanie przez łączenie podsumowanie Sortowanie n liczb - jeśli n=1 trywialne - rekursywne sortujemy 2 ciągi podłoga(n/2) i [n/2] liczb - łączymy dwa ciągi w czasie Teta(n) Strategia - podział problemu na mniejsze, ale analogiczne podproblemy - rekursywne rozwiązywanie podproblemów - Łączenie otrzymanych rozwiązań Złożoność tego to n ln n (zawsze tak jest dla procesu drzewiastego, on jest lepszy od sortowania przez wstawianie )a z kartami to n^2. Czas działania algorytmu może być reprezentowany przez następującą zależność rekurencyjną T(n)= Teta(1) if n=1 Lub 2T(n/2) + Teta(n) if n>1 Po rozwiązaniu dostajemy T(n) = Teta(n lg n) Wieże Hanoi Mamy trzy wieże oraz stos 64 dysków o zmniejszających się średnicach umieszczonych na pierwszej wieży. Potrzebujemy przenieść wszystkie dyski na inną wieżę. Zabronione jest położenie dysku większego na mniejszym. W każdym kroku wolno nam przenieść tylko jeden dysk. To się da zrobić dla dowolnej ilości krążków. Twierdzenie: Dla każdej liczby n da się przełożyć n krążków w wieżach Hanoi. Najmniejszy niech nazywa się 1 a największy n. Dzielę sobie te krążki na dwie części. Ogólnie można to zrobić indukcyjnie. Zakładamy, że umiemy przełożyć n-1 krążków i z tego ma wyniknąć, że da się przełożyć n krążków. Da się to pokazać nawet łatwo. Algorytm rekursywny INput ilość dysków, a,b,c wieże, wieża a zawiera wszystkie dyski OUtput a,b,c wieże, wieża b zawiera wszystkie dyski Hanoi(n,a,b,c) If n=1 then Move(a,b); Else Hanoi(n-1,a,c,b); Move(a,b); Hanoi(n-1,c,b,a); Wykłady z Algorytmów i Struktur Danych 7

8 Poprawność algorytmu łatwo pokazać przez indukcję względem n. To proces potęgowy względem 2, trwa on naprawdę długo. Ilość kroków M(n) potrzebnych do rozwiązania problemu dla n dysków spełnia zależność rekurencyjną M(1)=1 M(n)= 2M(n-1)+1 Rozwiązując tę zależność dostajemy to co jest na slajdach niestety niewyraźne Warto z tego wywnioskować, że ta metoda konstrukcji algorytmów jest atrakcyjna, zwykle się robi to rekurencyjnie, a z rekurencją trzeba uważać, komputery jej nie lubią. Nie zawsze łatwo jest podać warunek stopu by być pewnym, że on się zdarza było na pierwszym wykładzie. Tutaj ok. przykładem jest też obliczanie n tego wyrazu ciągu fibonacciego F1=f2=1 Fn=f_(n-1)+f_(n-2) Int fib(int n) { If(n<2) return 1; Else Return fib(n-1)+fib(n-2); } Liczenie fibonacciego rekurencyjnie jest niefajne bo buduje drzewo binarne dla policzenia fib(7) to np. element trzeci generujemy aż 5 razy a przecież zupełnie niepotrzebnie. To takie niebezpieczeństwo rekurencji, to że funkcja jest ładnie w kodzie napisana nie oznacza właśnie, żę będzie na pewno ok. Sortowanie Zaczniemy od tego by zdefiniować, czym jest sortowanie, bo niby wszyscy ten termin rozumiemy, ale definicja by się przydała. Potem będą podziały metod sortowania pod różnymi katami, by było wiadomo kiedy które stosować. Zaczniemy od metod klasycznych, prostych, znanych od dawna, ale nie mają najlepszych wyników czasowych, tyle że zawsze naukę zaczyna się od nich. {Potem będziemy je poprawiać. Metody klasyczne mają złożoność O(n^2), co znaczy, że jak mamy element to wykonujemy zbiór operacji na wszystkich innych elementach, wtedy właśnie czas wychodzi na poziomie kwadratowym i jak na sortowanie jest to zły czas. Będziemy omawiać sortowanie Stella które poprawia jedno z klasycznych sortowań kwadratowych, ono pozwala na wyjście z n^2. Będzie też sortowanie przez scalanie, które miało efektywniejszą złożoność obliczeniową niż n^2, bo ma O(nlogn). Czynnik logarytmiczny się pojawiał stad, ze się pojawiało drzewo binarne które miało tyle poziomów ile jest logn i na każdym poziomie było n operacji. No i będzie jeszcze QuickSort czyli sortowanie szybkie i po nim już metody kwadratowe nie były za bardzo stosowane. A na koniec spróbujemy obejrzeć metody sortowania w czasie liniowym, ale tutaj będą konieczne dodatkowe założenia. O(n) czyli to oznacza, żę dla każdego elementu możemy wykonać co najwyżej n operacji. To jest granica marzeń dla sortowania, dwie metody będą dawały taki czas uczciwie tyle żę za pewną cenę założeń, a będzie też sortowanie kubełkowe, które sprawia kłopoty, bo nie zawsze da taki fajny czas. Sortowanie zadanie definicja Wejście: ciąg n liczba=(a_1,a_2, a_n) Wyjście: permutacja (a_1,,a_n ) taka, że a_1 <= <=a_n Wykłady z Algorytmów i Struktur Danych 8

9 Po co sortować - podstawowy problem dla algorytmiki i skro ludzie się męczyli to wy też się męczcie, to jest dobre dydaktycznie, można pokazać wiele rzeczy - wiele algorytmów wykorzystuje sortowanie jako procedurę pomocniczą sortowanie często występuje jako podzadanie dużego zadania i jeśli będziemy umieli dobrze sortować, to nasze programy będą lepiej działały, bo niemalże zawsze wcześniej czy później trzeba coś uporządkować posortować. To taka ładna przesłanka praktyczna. - pozwala pokazać wiele technik - dobrze zbadane (czas) Zawsze jak sortujemy to musimy wiedzieć jakie jest kryterium, potrzebujemy też mieć ładną przechodnią relację,. Jeśli sortujemy ludzi to nie zmienią się ludzie, nie zmieni się ich miejsce jako grupa, zmieni się tylko porządek w jakim będą siedzieć. Można np. sortować tak sobie ludzi względem wieku itp., w efekcie otrzymamy zbiór ładnie posortowany, uporządkowany wg danej relacji. Wtedy jak weźmiemy dowolne dwa elementy to niższy indeks jest mniejszy od tego co ma wyższy indeks. To byłaby relacja jest starszy, a w wypadku liczb to jakieś porównywanie typu mniejszy, większy. Czyli dla liczb musimy zbudować relację taką, by te elementy zawsze były w tej relacji tak ze dowolne dwa są w relacji, wtedy wykorzystamy przechodniość relacji porządku i będzie dobrze. Sortowanie taksonomia Wewnętrzne i zewnętrzne - zależne od miejsca przechowywania zbioru (ram czy dysk) Wewnętrzne wtedy gdy mamy mało rzeczy do posortowania, mały zbiór, a zewnętrzne gdy zbiór jest duży np. baza PESEL Polaków. Sortowanie tablic i sortowanie list łączonych - zależnie od struktury danych (pliku), inaczej sortujemy w tablicy, inaczej w strukturach dynamicznych, które pozwalają na to by porządek logiczny elementów był inny niż porządek faktyczny w pamięci, rozbija się o to, że w tablicy jak chcemy posadzić pana w zielonym na miejscu pana w czerwonym to on zginie tak jest w tablicy, a bez tablic to np. ładnie się używa list łączonych czyli stosów, tam można ładnie wkładać element między dwa inne - różny sposób dostępu (bezpośredni dla tablicy, sekwencyjny dla listy) W miejscu lub nie - nie wymaga dodatkowej pamięci dla sortowania, czyli jeśli mam tablicę, to alokujemy drugą pamięć i przepisuję jedne elementy z tablicy do tej drugiej np. przesadzanie ludzi z jednego rzędu do innego pustego rzędu to jest to nie w miejscu, a lepiej jednak jest w miejscu, czyli bez konieczności alokacji miejsca Stabilne i niestabilne - kolejność elementów o tych samych wartościach klucza nie zmienia się. Inaczej kolejne sortowanie dla złożonych obiektów nie psuje efektów poprzedniego sortowania. Dla liczb nie widać co to jest,ale gdybyśmy brali ludzi po datach urodzenia i jeśli siedzi sobie dwóch panów urodzonych tego samego dnia jeszcze nieposortowanych, to metoda jest stabilna wtedy gdy nie przestawi ich. Czyli to metoda która nie przestawia równych elementów. Jest to po to by kolejnym sortowaniem nie psuć sobie wyników poprzedniego, bo np. gdy mamy książkę telefoniczną, to najpierw sortujemy po imionach a potem sortowaniem stabilnym sortujemy po nazwiskach. Stabilność jest decydująca w bazach danych. Problem polega na tym, że najszybsze metody są niestabilne. Bezpośrednie i pośrednie Wykłady z Algorytmów i Struktur Danych 9

10 - zależnie od tego przemieszczamy całe obiekty czy tylko wskaźniki (indeksy) do nich ma znaczenie praktyczne, możemy operować na strukturach danych których znamy adresy czyli może lepiej nie przemieszczać w pamięci obiektów tylko informacje o tym gdzie te obiekty mają być, zamieniamy same adresy czyli wskaźniki to jest sortowanie pośrednie Zestawienie czasów działania Przez wybór O(n^2) zawsze Bąbelkowe O(n^2) najgorszy przypadek, O(N) przypadek najlepszy Wstawianie O(N^2) średnio, O(N) najlepszy przypadek Shellsort O(N^(4/3)) (wykorzystuje sortowanie przez wstawianie i pozwala przejść z 2 do 4/3, czyli nieźle) Heapsort O(NlogN) zawsze (sortowanie przez kopcowanie) Mergesort O(NlogN) zawsze Quicksort O(NlogN) średnio; O(N^2) najgorszy przypadek (pomysł prosty i skuteczny, ale jest to sortowanie niestabilne prowadzi do procesu drzewiastego, coś się rozwidla itp) Zliczanie O(N) zawsze CountingSort (zależność liniowa, czyli jak zwiększymy zbiór elementów dwa razy złożoność wzrośnie dwa razy, jeśli ilość różnych wartości jest niewielka to jest sens je stosować np. liczby całkowite 1..10) RadixSort (Sortowanie pozycyjne) O(N) zawsze (tutaj chcemy by ilość pozycji byłą ograniczona) Zewnętrzne O(b logb) dla pliku o b stronach. Te ograniczenia nie mają sensu dla małej ilości elementów, gdy mamy mało elementów to najlepiej sortowanie przez wstawianie, tam czas rośnie szybko, ale dla małych elementów jest najszybsze. Sortowanie przez wybór Znajdujemy najmniejszy element ciągu (który jest w relacji z wszystkimi innymi, czyli np. dla relacji mniejszy równy znajdujemy minimum i chcemy spowodować, by to minimum stanęło na początku ciągu) i zamieniamy go z pierwszym elementem (taka zamiana w tablicy jest najmniejszym kosztem). Powtarzamy to dal podciągu bez pierwszego elementu itd. Można też sprawdzać, czy on nie stoi na początku, ale sprawdzenie warunku zawsze jest bardziej kosztowne niż ewentualne zamienienie elementu samego ze sobą. Gdyby to była lista, to wypinamy element z listy i wpinamy go na początek, niczego nie zamieniamy. Wtedy pierwszy element jest już ułożony, jego miejsce się nie zmienia, czyli pomijamy go i rozpatrujemy tablicę bez niego. Pytanie jak długo prowadzić ten proces? N-1 razy prowadzimy ten proces. A co by było gdyby elementy te ułożyły się wcześniej i przerwać cały proces wcześniej? Np to po pierwszym kroku jak sobie zamienimy 1 i 5 to już mamy ładne posortowanie. Czy da się coś takiego ładnie zobaczyć? Prowadzący tego nie zna, takiej metody taniej czasowo. Ale to nie jest dobre, bo jest dużo zadań w których mamy do czynienia z danymi bliskimi posortowania i być może ten proces się kończy wcześniej Selection_Sort(intA) 1. for i:=1 to length[a] 2. do min:=1; 3. for j:=i+1 to length[a] 4. do if A[j]<A[min] then min:=j; 5. Exchange A[min]<->A[i] (wymienia elementy ze sobą, trzy podstawienia) Jak mamy rozważać czy ta metoda jest stabilna to jest to zależne od tego w jaki sposób znajdujemy minimum I faktycznie ta stabilność jest ze względu na ostrą nierówność w Wykłady z Algorytmów i Struktur Danych 10

11 punkcie 4. Pętla zewnętrzna sterowana przez i odpowiada za skracanie rozpatrywanego ciągu, odpowiada za miejsce od którego zaczynamy poszukiwania. Druga pętla odpowiada za szukanie owego minimum. To jest ten wariant bez zastanawiania się czy minimum jest pierwszym elementem w ciągu, bo to się zwykle nie opłaca. Porównania i podstawienia to podstawowe operacje, które wpływają na czas. U nas zamian jest zawsze dla każdej linijki tyle samo. Przykład w Sedgewicku. Sortowanie przez wybór czas działania Zależność od danych wejściowych - ilość przebiegów: nie (zawsze N-1) - ilość porównań: nie - ilość Zajkina: nie O(N^2) zawsze (bez znaczenia jaki jest układ elementów w danych ważna jest tylko ilość). Sortowanie bąbelkowe (przez zamianę) Przechodzimy przez ciąg od jednego końca, porównując sąsiadujące elementy i ewentualnie zamieniając je miejscami. Powtarzamy tę procedurę aż do uporządkowania całego ciągu. Po pierwszym przejściu element minimalny znajduje się na początku a[0], po drugim na drugim miejscu znajduje się drugi co do wielkości a[1], po itd. To sortowanie w każdym kroku wyprowadza najmniejszy element na początek ciągu. Ono nigdy nie porównuje odległych od siebie elementów to jak z porównywaniem wzrostu najłatwiej się porównuje ludzi stojących blisko siebie, a trudno gdy te osoby stoją daleko od siebie. Czyli porównujemy ostatni z przedostatnim, jeśli on jest mniejszy lub równy od przedostatniego to trzeba zamienić miejscami, jeśli nie to nic nie robimy i przechodzimy do następnej pary. Jeśli minimum będzie porównywane z jakimkolwiek to będzie musiał być zamieniany, przepychany do przodu. Efekt będzie taki sam jak przy sortowaniu przez wybór ale koszt jest większy bo jest więcej zamian. Gdy zostanie jeden element to nie ma go z czym porównać i na pewno jest największy. Ale kiedy nie zostanie wykonana żadna zamiana to wtedy można już skończyć, wystarczy mieć flagę, która będzie sprawdzać, czy jakaś zamiana została wykonana czy nie. Wadą tego jest fakt, że jeśli mamy to jeśli jadę od prawej to wystarczy jeden przebieg a jeśli od lewej to nagle mam masę operacji, czyli metoda ta jest wrażliwa na kierunek. Buble_sort(a) 1. for i:=1 to length[a] 2. do for j:=length[a] downto i+1 3. do if A[j]<A[j-1] 4. exchange Iteratory I oraz j odpowiadają podobnie jak wcześniej. Sortowanie bąbelkowe czas wykonania Zależność od danych wejściowych: - ilość potrzebnych przejść: tak - ilość porównań w jednym przejściu: nie - ilość zmian: tak Najlepszy przypadek O(N) - jeśli elementy są już posortowane - tylko jedno przejście, stąd mamy N-1 porównań i 0 zamian Najgorszy przypadek O(N^2) - dane odwrotnie posortowane Wykłady z Algorytmów i Struktur Danych 11

12 - n-1 przejść - (n-1)n/2 porównań i (n-1)n/2 zamian Mówił jeszcze o sortowaniu przez wstrząsanie. Sortowanie przez wstawianie Insertion_Sort(A) 1. for j:=2 to length[a] 2. do key:=a[j] 3. i:=j-1 4. while i>0 and A[j]>key 5. do A[j+1]:=A[j] 6. i:=j-1 7. A[i+1]:=key Widać, że ta metoda działa w zależności od danych, pętla while będzie szybciej wykonana, gdy ten ciąg będzie posortowany nie będzie potrzeby wykonywania jej. Gdyby tej pętli nie było to złożoność byłaby liniowa, proces byłyby powtarzany tyle razy jaka jest długość ciągu, bo tylko while jest zależna od ilości elementów. Sortowanie prze wstawianie czas działania Zależność od danych wejściowych -ilość iteracji: nie (zawsze N-1) - ilość porównań: tak - ilość zamian: tak Najgorszy przypadek O(n^2) - elementy odwrotnie posortowane - (N-1)N/2 porównań i (N-1)N/2 zamian Najlepszy przypadek O(N) - elementu już posortowane - jedno porównanie i zero zamian w każdej iteracji, razem n-1 porównań i brak zamian Sortowanie ciąg dalszy Powtórzenie Przypomnijmy, że my będziemy sortować liczby, ale sortować można wszystkie obiekty jeśli tylko mamy zdefiniowane co to znaczy, że jedne obiekt jest w relacji z drugim. Sortowanie wewnętrzne sortowanie małych zbiorów, na tyle małych, że się naraz mieszczą w pamięci komputera i zwykle właśnie o tych metodach mówimy i zwykle wtedy się ma do czynienia z sortowaniem w miejscu, wtedy jest fajna oszczędność. Niektóre metody mogą być stosowane i wewnętrznie i zewnętrznie, ale nie wszystkie mogą być i takie i takie. Jeśli metoda jest stabilna to może być stosowana wielokrotnie, kolejne sortowanie nie burzy wcześniejszego porządku. Klasyczne metody czyli pierwsze trzy mają złożoność O(n^2), czyli jeśli 100 elementów sortowaliśmy w 2 sekundę to 200 elementów sortujemy w cztery sekundy. Przypomnijmy: f(n)=o(g(n)) to znaczy, że istnieje stała c taka, że od pewnego momentu f(n)<=c*g(n). Ta stała c nie musi być zawsze równa 1, czyli od pewnego miejsca wykres f jest poniżej c*g. Wszystkie sensowne metody powinny mieć czas nie gorszy niż to n^2, bo już właśnie ten czas wcale nie jest najlepszy. Jeśli wezmę element i dla niego Wykłady z Algorytmów i Struktur Danych 12

13 wykonam operacje na wszystkich innych n elementach to wtedy mamy metodę n^2, czyli jeśli jest metoda która dla jakiegoś obiektu robi cos z innymi to znaczy ze mamy n^2. Wiemy, że istnieją sortowania o złożoności liniowej. Zastanawiamy się, czy to dobrze, czy źle. Prawda jest taka, że to jest najlepsza możliwość, bo to znaczy, że dla każdego elementu możemy wykonać co najwyżej stałą liczbę operacji. Gdybyśmy mieli rozważać, że mamy lepszą metodę niż O(n) czyli mielibyśmy być lepsi od funkcji liniowej, to w praktyce dla bardzo dużych n to by oznaczało, że istnieją elementy których w ogóle nie oglądamy, nic z nimi nie robimy, doszlibyśmy do momentu gdzie mamy więcej operacji niż ilości elementów, takie umienie posortowania bez oglądania elementów. Istnieją algorytmy takie, których czas jest poniżej n np. wypisać pierwszy element tablicy, wtedy przecież nie musimy oglądać wszystkich elementów tablicy, tylko właśnie czas jest lepszy niż liniowy. Zewnętrzne O(b logb) dla pliku o b stronach. Operacje wejścia, wyjścia są znacznie dłuższe od operacji wewnętrznych, bo jedno czytanie potrafi zniweczyć całą oszczędność czasu. Dlatego mówimy tutaj o stronach, a nie o jakiejś zależności od n. Sens sortowania bąbelkowego jest taki, że jak porównujemy nie liczby tylko np. ludzi to łatwiej porównać ludzi obok siebie niż od siebie odległych, a poza tym ta metoda pozwala łatwo stwierdzić, czy można już skończyć, bo przy sortowaniu przez wybór musieliśmy zawsze wykonać n-1 przebiegów a tutaj jak w jakimś przebiegu nie wykona się żadnej zamiany to wiadomo, że już nigdy się jej nie wykona i metodę można zatrzymać. W sortowaniu przez wstawianie ciężko jest wsadzić element pomiędzy dwa inne, w liście nie ma problemu, a w tablicy? Powiedzmy że mamy Najpierw jak chcemy wstawić czwórkę, to zapamiętujemy tą 4 gdzie indziej czyli wtedy zwolniliśmy miejsce w którym ta 4 była i wtedy porównujemy z ostatnim elementem do którego chcemy wstawić czyli z 7 i albo wstawiamy 4 przed albo za nasz element. W razie potrzeby przepisujemy siódemkę o jeden do tyłu. Potem robimy to samo z kolejnym u nas z 6 no i przepisuję ją na przedostatnie miejsce, przez chwilę mam dwie 6, a w pamięci, w tej dodatkowej komórce mam naszą 7 którą wcięło. Pytamy teraz po co jest warunek A[j]>key jest po to bo byłby problem gdyby nasz wstawiany element był najmniejszy od wszystkich innych, czyli wtedy trzeba by było wsadzić na początek, a by tego uniknąć, to można np. zrobić jeden przebieg bąbelkowy, wtedy już najmniejszy element będzie na początku i będzie cudnie. Insertion_Sort(A) 8. for j:=2 to length[a] 9. do key:=a[j] 10.i:=j-1 11.while i>0 and A[j]>key 12.do A[j+1]:=A[j] 13.i:=j-1 14.A[i+1]:=key Pętla while mówi ile elementów zostało przepisanych do tyłu, jak długo ten element wędrował, w najgorszym przypadku będzie to cały ciąg, w najlepszym będzie od razu wskakiwał na swoje miejsce i im krótsza ta trasa tym lepiej dla naszej metody czyli najlepiej zadbać o to by ta pętla się nie wykonywała długo. Dlatego Stell wymyślił metodę by polepszyć to i mamy sortowanie: ShellSort pomysł - modyfikacja(rozszerzona wersja) sortowania przez wstawianie - dążymy do zmniejszania ilości zamian albo ciągi krótkie albo lepsze (bliższe posortowania) Wykłady z Algorytmów i Struktur Danych 13

14 - shell sort wykonuje sortowanie podciągów: - - wybieramy ciąg liczb (zwany ciągiem przyrostów) h_1=1, h_t> >h_2>h_1 - sortujemy ciągi elementów odległych o h_t, H_(t-1), h_(t-2),,h_1 Sortowanie przez wstawianie byłoby fajniejsze, gdyby nasz ciąg był coraz bliższy posortowaniu, by literki blisko siebie się za bardzo nie różniły, wtedy pętla while będzie się krótko wykonywać, a do tego dążymy. Ale to dopiero z czasem. A np. fajnie na początku jeździć w krótkim ciągu, Jak mamy do czynienia z długim ciągiem to sortujemy na początku kawałki jego, stopniowo sortujemy coraz dłuższe kawałki, ale tak je dobieramy byśmy mieli coraz lepsze ciągi tj coraz bliższe posortowania. Shell wymyślił że bierzemy ciąg przyrostów który określa na ile podciągów tniemy nasz ciąg. Jeśli chcę posortować na 4 części to możemy wziąć co czwarty element i tak sortujemy takie nasze cztery podciągi. Możemy potem pociąć na mniejszą ilość np. na dwa, ten ciąg będzie dłuższy ale za to lepszy, na koniec i tak będzie trzeba choć raz posortować go. Pamiętajmy, ze sortowanie przez wstawianie ma złożoność T=O(n^2). Zatem jeśli sobie dzielę np. cztery części to metoda była kwadratowa, czterokrotnie się zmniejszyła ilość elementów, to czas się zmniejszy 1/16 czasu i jest 4 takie kawałki teraz pytamy ile wynosi posortowanie wszystkich tych czterech kawałków z osobna: T/4. Czyli mamy jeszcze do dyspozycji 3/4T Weźmy, że najpierw tniemy na 7 kawałków, potem na 3 kawałki i na końcu mamy 1- takie zwykłe sortowanie przez wstawianie, czyli najpierw bierzemy co siódmy element. Pierwszy podciąg to: podciąg krótki, da się szybko posortować Jak zrobię tak dla wszystkich to nasz ciąg będzie nadal nieposortowany, ale już bliżej posortowaniu niż wcześniej typu raczej nie spotkam na początku 9 itp. Kluczowe jest to by wziąć odpowiedni ciąg przyrostów, ale nie ma raczej żadnej sensownej metody jak sortować, jak wybierać te przyrosty, Shell zaproponował by brać [potęgi dwójki, ale okazuje się, że ten pomysł jest fatalny. Ciąg przyrostów ma więcej elementów im więcej jest wyrazów do posortowania. Przykład na ów ciąg przyrostów skopiowany z sedgewicka jest na zdjęciach Mergesort pomysł sortowanie przez łączenie Jako przykład metody dziel i zwyciężaj. Dzielimy ciągi na podciągi jakkolwiek ale zwykle na połowę i przestajemy gdy dojdziemy do podciągu, który jest już posortowany, czyli w sumie jednoelementowych bo tylko wtedy mamy gwarancję posortowania. Czyli mamy ciągi jednoelementowe i łączymy jednoelementowe w dwuelementowe w ten sposób, by wynik był dalej posortowany, no i dalej łączymy ze sobą. Metoda ta nie zakłada, by łączone ze sobą ciągi były tej samej długości. Czyli rzecz opiera się na dwóch procesach proces rozdzielania gdy mamy ciąg o długości większej niż jeden i dzielę na połówki, wywołuję naszą funkcję dla tych połówek a na koniec łączę. Zatem potrzebujemy dodatkowego miejsca przy tym sortowaniu, nei jest ono sortowaniem w miejscu, choć da się go w miejscu zrealizować, lecz wówczas wzrasta stopień komplikacji. Przykłady na slajdach MergeSort(a,p,r) 1. if p<r 2. then q:=podloga((p+r)/2) Wykłady z Algorytmów i Struktur Danych 14

15 3. MergeSort(a,pg) 4. MergeSort(A,q+1,r) 5. Merge(A,p,q,r) Merge(A,p,q,r) 1. n1:=q-p+1 2. n2:=n-q 3. create arrays L[1..n1+1] and R[1..n2+1] 4. for i:=1 to n1 5. do L[i]:=A[p+i-1] 6. for j:=1 to n2 7. do R[j]:=A[q+j] 8. L[n1+1]:=infty 9. R[n2+1]:=infty 10. i:=1 11. j:=1 12. for k:=p to r 13. do if L[i]<R[j] 14. then A[k]:=L[i] 15. i:=i else A[k]:=R[j] 17. j:=j+1 Sortowanie Quicksort i Heapsort(sortowanie prze kopcowanie) Poprzednio opowiadaliśmy o metodach sortowania działających w czasie kwadratowym i doszliśmy do ShellSort działało to lepiej nieco niż kwadrat O(N^(4/3)). Heapsort ma złożoność O(NlogN) zawsze, a QuickSort ma średnio też O(NlogN), a najgorszy przypadek to O(N^2). Już mówiliśmy o MergeSort które też miało złożoność O(NlogN). Heap kopiec, inne znaczenie to sterta, stertę odnosi się do pamięci, a kopiec do struktury danych. Pamiętamy, ze istnieją też metody lepsze, optymalne, ale one nie są ogólne, bo nie ma metod sortujących w czasie liniowym BEZ dodatkowych założeń. Pochód zamykają metody zewnętrzne realizowane są w ten sposób, że nie wykonuje się jednoczesnych operacji na wszystkich danych(bo np. jest ich zbyt dużo), działamy tylko na części danych. Sortowanie przez łączenie może być zrobione jako metoda zewnętrzna i wewnętrzna. Przy sortowaniu zewnętrznym istotne jest ile operacji musze wykonać na jednej stronie, czyli na jednym zaczytaniu. Quicksort jest bardzo popularny i szybki w średnim przypadku. Heapsort wykorzystuje strukturę kopca. Jak rozmawiamy o złożoności i mamy tam logarytm, to zwykle w nim podstawą jest dwójka. Łatwo sobie wyobrazić skąd się bierze czynnik kwadratowy(na każdym elemencie wykonujemy operacje dla wszystkich innych elementów, lub nawet jeśli nie dla wszystkich czyli np. dla szukania maksimum to i tak otrzymamy czas kwadratowy), a skąd bierze się czynnik logarytmiczny? Stąd, że jest struktura drzewiasta i trzeba wykonać operację na każdym poziomie drzewka których jest logn i na każdym poziomie wykonujemy n operacji. Z procesem liniowym byśmy mieli do czynienia wtedy, gdy dla każdego elementu wykonamy stałą ilość operacji. Tylko pamiętajmy, że mówimy o asymptotycznej zależności czyli musimy wziąć naprawdę dużą ilość elementów by określić złożoność czasową. QuickSort stosuje się znacznie częściej niż HeapSort, bo pierwsza opcja jest łatwiejsza, jeśli potrzebujemy tylko sortować, to kopiec nie jest fajny, lae jak potrzebujemy coś poza sortowaniem z tym robić to kopcowanie ma już większy sens. Wykłady z Algorytmów i Struktur Danych 15

16 QuickSort Jest to najszybszy w praktyce algorytm sortowania pozwala na efektywne implementacje. Pomysł polega na tym, by w każdym kroku ustawić jedne element i przestać się nim zajmować. Czyli mam ileś elementów, wybieram pierwszy lepszy, to będzie mój element osiowy i musimy zrobić coś, by ten jeden element był dobrze ustawiony. Mianowicie sprawdzam ile jest elementów od mojego mniejszych, ile jest większych i ustawiam te mniejsze na lewo, a większe równe na prawo. Wtedy te mniejsze będą już zawsze z lewej strony, nigdy na prawą nie wskoczą, czyli zapominam o moim elemencie, mam dwa ciągi ten na lewo i ten na prawo i powtarzam całą procedurę,. Mam wiec rekurencję. Pytanie, kiedy go warto przerwać? Gdy mamy jedno elementowy lub zero elementów. Raczej zero, bo jak będzie jeden to możemy akurat trafić na tej największy. Procedura: - wybieramy element osiowy (Pivot) - dzielimy ciąg na dwa podciągi elementów mniejszych lub równych od osiowego oraz większych od osiowego. Powtarzamy takie postępowanie aż osiągniemy ciąg długości 1. - algorytm typu dziel i zwyciężaj - jest to metoda sortowania w miejscu (podobnie jak InsertSort w przeciwieństwie do MergeSort), czyli nie wymaga dodatkowej pamięci Czyli problemem jest wybór elementu osiowego i podział (partition). Musimy dobrze zaimplementować funkcję podziału. Element osiowy można losować, ale jest kilka lepszych strategii. Wybór tego elementu jest ważny o tyle, bo jeśli będziemy szczególnie źle wybierać te elementu to metoda się zdegeneruje. Najlepiej jest gdy dostajemy w miarę równe części, czyli element osiowy jest bliski środka, a NIE chcemy gdy po jednej stornie mamy prawie wszystkie element, to będzie prowadziło do czasu kwadratowego. Kod programu Quicksort(A,p,r) (p-poczatek, r-prawy) 1. if p<r (czyli w ogóle cośjest w tej rablicy) 2. then q:=partition(a,p,r) (wybieram element osiowy) 3. Quicksort(A,p,q-1) 4. QUicksort(A,q+1,r) Problem podziału Funkcja partition dzieli ciąg na dwa podciągi : elementów mniejszych (bądź równych) od osiowego i większych od niego. Nie ma znacznie czy te równe wciśniemy na lewo czy na prawo, ale ważne by być tu konsekwentnym. Wystarczy ten ciąg przejrzeć raz by sobie ładnie podzielić na te dwie części. Na przykładzie ze slajdów mamy ostatni element jak ostatni bo jest to szybka strategia, nie muszę się zastanawiać który to element wystarczy ze wiem, że jest ostatni. Od początku ciągu szukamy elementów które są za duże od naszego osiowego. Gdy znajdziemy to zatrzymujemy się na ostatnim obiekcie, mamy tu naturalnego wartownika w postaci n. Od prawej szukamy mniejszych elementów, gdy znajdziemy taką parę z jednej strony za duży a z drugiej za mały, to zamieniamy je miejscami ze sobą. Przerwiemy ten proces wtedy, gdy te indeksy się spotkają, w tym miejscu będą z jednej strony element mniejsze, z drugiej większe i w to miejsce wystarczy włożyć nasz element osiowy. Pamiętajmy, ze to tablica, nie da się niczego wepchnąć, ale sortowanie przez wybór załatwi sprawę lub bierzemy pierwszy duży i zamieniamy z naszym N. Czyli tylko raz przeglądaliśmy ciąg. Można powiedzieć, że najgorszy przypadek to gdy zawsze musieliśmy w każdym porównaniu dokonać też zamiany i jednak nadal procedura jest zależna tylko od ilości elementów. Wykłady z Algorytmów i Struktur Danych 16

17 Strategia wyboru elementu osiowego Opcja 1 Zawsze wybieramy skrajny element (pierwszy lub ostatni), najczęściej stosowana - zalety: szybkość - wady: jeśli trafimy na najmniejszy (największy) element podział nie redukuje istotnie problemu Opcja 2 Wybieramy losowo - zalety: średnio powinno działać dobrze (podział na podciągi o zbliżonej długości), skoro jest ten algorytm losowy to nie da się odpowiednio źle dobrać przykładu - wady: czasochłonne i nie gwarantuje sukcesu, bo możemy zawsze losować minimum, prawdopodobieństwo jest bardzo małe, ale nadal istnieje Opcja 3 Wybieramy medianę z pierwszych/ostatni/środkowych 3/5/7 elementów (mediana to środkowa) - gwarantuje, że nie będzie zdegenerowanych podciągów (pustych), czyli zawsze przynajmniej jeden element zostanie po którejś ze stron, nie będzie sytuacji zdegenerowanej - kompromis pomiędzy opcją 1 i 2 - jednak nie daje pewności, bo możemy zawsze losować prawie maksimum, choć znów prawdopodobieństwo jest małe Pseudokod opcji 1 Partition(A,Left,Right) 1. Pivot:=A[Right] 2. i=left-1 3. for j:=left to Right do if (A[j]<=Pivot) 5. then i=i+1 6. exchange (A[i],A[j]) 7. exchange(a[i+j],a[right]) 8. return i+1 Randomizowany Quicksort(opcja 2) - zakładamy, że nie ma powtórzeń - jako element osiowy wybieramy losowy element ciągu (opcja 2) - powtarzamy procedurę, wszystkie podziały są równe prawdopodobne (1:n-1, 2:n- 2,,n-1:1), z prawdopodobieństwem 1/n - randomizacja jest drogą do unikania najgorszego przypadku (zwłaszcza przy dobrym generatorze danych losowych) Kod Randomized-Partition(A,p,r) 1. i:=random(p,r) 2. Exchange A[r]<->A[i] 3. return Partition(A,p,r) Randomized QuickSort(A,p,r) 1. if p<r then 2. q:=randomized-partition(a,p,r) Wykłady z Algorytmów i Struktur Danych 17

18 3. Randomized-Quicksort(A,p,q) 4. Randomized-Quicksort(A,q+1,r) Quicksort czas działania Najgorszy przypadek to O(N^2) podciągi mają długości 0 i N-1 (element osiowy zawsze jest najmniejszy/największy) np. dla posortowanego ciagi i pierwszej opcji wyboru elementu osiowego. T(N)=T(0)+T(N-1)+N=T(N-1)+N=O(N^2) Najlepszy przypadek O(NlogN) podział jest zawsze najlepszy N/2, element osiowy jest zawsze medianą. T(N)=T(N/2)+N=O(NlogN) Średni przypadek O(NlogN) trzeba uważać, co to miałoby znaczyć, ale dla analizy probabilistycznej to właśnie tak wyjdzie. T(N)=i/N*suma_(i=0)^(N-1) T(N-i- 1)+N=2/N*suma po j+0 do N-1 z T(j)+N=O(NlogN) Podciągi otrzymane w wyniku podziały są równe to czas zapisuje się w postaci równania T(n)=2T(n/2)+Teta(n) (Teta to czas tego partition) i po posumowaniu dostaniemy czas logarytmiczny, na fotce mamy drzewko obrazujące długości ciągów otrzymywanych po lewej i prawej stronie, binarne kompletne drzewo budowane poziomami. Oraz ten najgorszy przypadek przypominający listę liniową i dostaniemy po zsumowaniu czas kwadratowy T(N)=T(i)+T(N-i-1) +N for N>1 T(0)=T(1)=1 T(i) oraz T(N-i-1) dla podziału i?n-i-1 N dla podziału1/n-1 (liniowe, przeglądamy wszystkie elementy) Uwagi Małe ciągi. QuickSort źle się zachowuje dla krótkich ciągów. Poprawa jeśli podciąg jest mały zastosować sortowanie przez wstawianie (zwykle dla ciągów o długości 5-20), bo dla małych ciągów muszą nam się te ciągi degenerować. Porównanie z mergesort: - oba zbudowane są na zasadzie dziel i zwyciężaj (czyli zmniejszania zadania), podobny czas, logarytm pojawiał się z tego samego powodu - mergesort wykonuje sortowanie w fazie łączenia (to było tak, że najpierw dzieliliśmy na mniejsze części i gdy doszliśmy do ciągów jednoelementowych to w momencie łączenia było sortowanie, czyli jeśli wejścia były posortowane to ona po łączeniu zachowywała porządek). - quicksort wykonuje prace w fazie podziału, czyli znajdujemy te małe, duże elementy i dopiero dzieląc = wstawiając nasze N to mamy sortowanie. Heap Sort pojęcie kopca Struktura kopca binarnego Drzewo binarne(bliskie zrównoważenia), wszystkie poziomy z wyjątkiem co najwyżej ostatniego, kompletnie zapełnione, chcielibyśmy by były dokładnie wszystkie zapełnione uda się jeśli będzie 2^n-1 elementów, a to dlatego bo na zerowym poziomie jest jeden element, na pierwszym są dwa elementy w takim tradycyjnym drzewku, na drugim poziomie są 4 elementy, a na k tym poziomie mamy 2^k, czyli drzewo binarne o k poziomach ma dokładnie 2^0 + 2^1+2^2+ +2^k elementów. Wartość klucza(tej liczby która jest w węźle) w węźle(to z czego wychodzą gałęzie) jest większa lub równa od wartości kluczy wszystkich dzieci. Własność taka jest zachowana dla lewego i prawego poddrzewa (zawsze). Czyli maksimum jest w korzeniu, taką strukturę nazywamy kopcem, może być przechowywane w drzewie, ale będziemy zwykle trzymać je w tablicy, gdzie w każdej jest jeden poziom i nie będzie pustych Wykłady z Algorytmów i Struktur Danych 18

19 miejsc w niej. Ostatni poziom może nie być kompletny, ale wtedy będzie po prostu krótsza tablica i tyle. Przykład na fotkach (by znaleźć czyjeś dziecko to wystarczy pomnożyć jego indeks przez dwa, a jeśli chcemy naleźć rodzica to bierzemy całkowitą połówkę). Oczywiście tka się da dla przechowywania danych w tablicy. Mnożenie, dzielenie przez dwa jest bardzo szybkie bo się niczego nie dzieli tylko przesuwa rejestr. Zauważmy połączenia w drzewie dzieci węzła i występują na pozycjach 2i oraz 2i+1. Jest to wygodne, bo dla reprezentacji binarnej dzieleniu/mnożeniu przez 2 odpowiada przesuwanie (szybka operacja), a dodawanie jedynki oznacza zmianę najmłodszego bitu (po przesunięciu) Kopcowanie (Heapify) Jeden element jest zawsze dobrym kopcem, rozważam teraz sytuację, gdy mam dwa kopce i chcę je połączyć ze sobą tak, by po połączeniu nadal mieć kopiec. Po pierwsze sprawdzamy, czy tak jest dobrze od razu,. Jeśli nie, to znajdujemy większe dziecko i zamieniamy z nim. - niech i będzie indeksem w tablicy A - niech drzewa binarne Left(i) i Right(i) będą kopcami - Ale A[i] może być mniejsze od swoich dzieci co powoduje załamanie własności kopca - metoda kopcowania przywraca własności kopca dla A poprzez przesuwanie A[i] w dół kopca aż do momentu, kiedy własność kopca jest już spełniona. Kod kopcowania na fotkach zeskanowany z książki, wiec z dziwnymi oznaczeniami. Na fotkach przykład. Kopcowanie czas działania Czas działania procedury Heapify dla poddrzewa o n węzłach i korzeniu w i: - ustalenie relacji pomiędzy elementami to Teta(1) - dodajemy czas działania Heapify dla poddrzewa o korzeniu w jednym z potomków i, gdzie rozmiar tego poddrzewa 2n/3 jest najgorszym przypadkiem T(n)<=T(2n/3)+Teta(1) => T(n)=O(logn) Inaczej mówiąc, czas działania dla drzewa o wysokości h jest O(h). Budowa kopca - konwertujmy tablicę A[1..n], gzie n=length[a] na kopiec - zauważmy, że elementu w A[(podłoga(n/2)+1)..n] są już zbiorem kopców jednoelementowych! Build-Heap(A) 1 for i:=podloga(n/2) downto 1 2 do heapify Znów przykład na fotkach. Analiza Poprawność: indukcja po i (wszystkie drew o korzeniach m>i są kopcami) Czas działania n wywołań kopcowania =no(lgn)=o(nlogn) Wystarczająco dobre ograniczenie O(nlogn) dla zadania sortowanie, ale czasem kopiec budujemy dla innych celów. HeapSort (A) Analysis 1. Build-Heap(A) O(n) 2. for i:=n downto 2 n times 3. do exchange A[1]<->A[i] O(1) 4. n:=n-1 O(1) 5. Heapify(A,1) logn Wykłady z Algorytmów i Struktur Danych 19

20 Czas działania O(nlogn)+czas budowy kopca O(n). Przykładzik na drzewach na fotach jak z kopca dostać posortowaną tablicę. Sortowanie o złożoności obliczeniowej na poziomie liniowym Są dwie takie metody: sortowanie przez zliczanie oraz sortowanie radix sort, jest jeszcze sortowanie kubełkowe, które już różnie daje tą złożoność. Czyli są to metody lepsze od tych o złożoności NlogN. Jednak by mieć tą złożoność liniową są konieczne dodatkowe założenia, a nie było tej konieczności dla tych NlogN tj MergeSort, HeapSort i QuickSort. Założenia które tu trzeba zrobić wcale nie są takie małe ani łatwe do spełnienia. Sortowanie przez zliczanie (counting sort) To sortowanie nie jest sortowaniem w miejscu zatem nie może być stosowane dla dużych zbiorów, poza tym wymaga ograniczenia warttości. Radix-Sort Sortowanie pozycyjne, wymaga też by wartości na poszczególnych pozycjach pochodziły z dość niewielkiego zbioru. Sortowanie kubełkowe (bucket sort) Zakłada, żę elementy są równomiernie rozłożone. Dodatkowe założenia dotyczą oczywiście danych wejściowych. Przykłady takich założeń: Dane są liczbami całkowitymi z przedziału [0..k] i k=o(n), Dane są liczbami wymiernymi z przedziału [0,1] o rozkładzie jednostajnym na tym przedziale. Trzy algorytmy: Counting Sort (zliczanie) Radix Sort Bucket Sort Sortowanie przez zliczanie Liczymy ile jest elementów poszczególnych rodzajów w tym ciągu i próbujemy ustalić ile powinno być przed nim. Jeśli mamy powtórzenia to zwykle znajduje się pozycję pierwszego i następne umieszczamy za nim Wejście: n liczb całkowitych z przedziału [0..k], dla k=o(n). Pomysł: dla każdego elementu wejścia x określamy jego pozycję (rank):ilość elementów mniejszych od x. Jeśli znamy pozycję elementu umieszczamy go na r+1 miejscu ciągu. Przykład: Jeśli wiemy, że w ciągu jest 6 elementów mniejszych od 17, to 17 znajdzie się na 7 miejscu w ciągu wynikowym. Powtórzenia: jeśli mamy kilka równych elementów umieszczamy je kolejno poczynając od indeksu pozycja Wykłady z Algorytmów i Struktur Danych 20

Wykład 2. Poprawność algorytmów

Wykład 2. Poprawność algorytmów Wykład 2 Poprawność algorytmów 1 Przegląd Ø Poprawność algorytmów Ø Podstawy matematyczne: Przyrost funkcji i notacje asymptotyczne Sumowanie szeregów Indukcja matematyczna 2 Poprawność algorytmów Ø Algorytm

Bardziej szczegółowo

Wykład 5. Sortowanie w czasie liniowologarytmicznym

Wykład 5. Sortowanie w czasie liniowologarytmicznym Wykład 5 Sortowanie w czasie liniowologarytmicznym 1 Sortowanie - zadanie Definicja (dla liczb): wejście: ciąg n liczb A = (a 1, a 2,, a n ) wyjście: permutacja (a 1,, a n ) taka, że a 1 a n 2 Zestawienie

Bardziej szczegółowo

Wykład 3. Metoda dziel i zwyciężaj

Wykład 3. Metoda dziel i zwyciężaj Wykład 3 Metoda dziel i zwyciężaj 1 Wprowadzenie Technika konstrukcji algorytmów dziel i zwyciężaj. przykładowe problemy: Wypełnianie planszy Poszukiwanie (binarne) Sortowanie (sortowanie przez łączenie

Bardziej szczegółowo

Wykład 4. Sortowanie

Wykład 4. Sortowanie Wykład 4 Sortowanie 1 Sortowanie - zadanie Definicja (dla liczb): wejście: ciąg n liczb A = (a 1, a 2,, a n ) wyjście: permutacja (a 1,, a n ) taka, że a 1 a n Po co sortować? Podstawowy problem dla algorytmiki

Bardziej szczegółowo

Zaawansowane algorytmy i struktury danych

Zaawansowane algorytmy i struktury danych Zaawansowane algorytmy i struktury danych u dr Barbary Marszał-Paszek Opracowanie pytań teoretycznych z egzaminów. Strona 1 z 12 Pytania teoretyczne z egzaminu pisemnego z 25 czerwca 2014 (studia dzienne)

Bardziej szczegółowo

TEORETYCZNE PODSTAWY INFORMATYKI

TEORETYCZNE PODSTAWY INFORMATYKI 1 TEORETYCZNE PODSTAWY INFORMATYKI 16/01/2017 WFAiS UJ, Informatyka Stosowana I rok studiów, I stopień Repetytorium złożoność obliczeniowa 2 Złożoność obliczeniowa Notacja wielkie 0 Notacja Ω i Θ Rozwiązywanie

Bardziej szczegółowo

Strategia "dziel i zwyciężaj"

Strategia dziel i zwyciężaj Strategia "dziel i zwyciężaj" W tej metodzie problem dzielony jest na kilka mniejszych podproblemów podobnych do początkowego problemu. Problemy te rozwiązywane są rekurencyjnie, a następnie rozwiązania

Bardziej szczegółowo

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie. Sortowanie Dane wejściowe: ciąg n-liczb (kluczy) (a 1, a 2, a 3,..., a n 1, a n ) Dane wyjściowe: permutacja ciągu wejściowego (a 1, a 2, a 3,..., a n 1, a n) taka, że a 1 a 2 a 3... a n 1 a n. Będziemy

Bardziej szczegółowo

Algorytmy i struktury danych

Algorytmy i struktury danych Algorytmy i struktury danych Proste algorytmy sortowania Witold Marańda maranda@dmcs.p.lodz.pl 1 Pojęcie sortowania Sortowaniem nazywa się proces ustawiania zbioru obiektów w określonym porządku Sortowanie

Bardziej szczegółowo

Sortowanie przez scalanie

Sortowanie przez scalanie Sortowanie przez scalanie Wykład 2 12 marca 2019 (Wykład 2) Sortowanie przez scalanie 12 marca 2019 1 / 17 Outline 1 Metoda dziel i zwyciężaj 2 Scalanie Niezmiennik pętli - poprawność algorytmu 3 Sortowanie

Bardziej szczegółowo

Sortowanie w czasie liniowym

Sortowanie w czasie liniowym Sortowanie w czasie liniowym 1 Sortowanie - zadanie Definicja (dla liczb): wejście: ciąg n liczb A = (a 1, a 2,, a n ) wyjście: permutacja (a 1,, a n ) taka, że a 1 a n Po co sortować? Podstawowy problem

Bardziej szczegółowo

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

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami Przykład 1. Napisz program, który dla podanej liczby n wypisze jej rozkład na czynniki pierwsze. Oblicz asymptotyczną złożoność

Bardziej szczegółowo

Algorytmy i złożoność obliczeniowa. Wojciech Horzelski

Algorytmy i złożoność obliczeniowa. Wojciech Horzelski Algorytmy i złożoność obliczeniowa Wojciech Horzelski 1 Tematyka wykładu Ø Ø Ø Ø Ø Wprowadzenie Poprawność algorytmów (elementy analizy algorytmów) Wyszukiwanie Sortowanie Elementarne i abstrakcyjne struktury

Bardziej szczegółowo

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

Podstawowe algorytmy i ich implementacje w C. Wykład 9 Wstęp do programowania 1 Podstawowe algorytmy i ich implementacje w C Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 9 Element minimalny i maksymalny zbioru Element minimalny

Bardziej szczegółowo

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n ) SORTOWANIE 1 SORTOWANIE Proces ustawiania zbioru elementów w określonym porządku. Stosuje się w celu ułatwienia późniejszego wyszukiwania elementów sortowanego zbioru. 2 Definicja Ciąg wejściowy: a 1,

Bardziej szczegółowo

Teoretyczne podstawy informatyki

Teoretyczne podstawy informatyki Teoretyczne podstawy informatyki Wykład 4a: Rozwiązywanie rekurencji http://kiwi.if.uj.edu.pl/~erichter/dydaktyka2010/tpi-2010 Prof. dr hab. Elżbieta Richter-Wąs 1 Czas działania programu Dla konkretnych

Bardziej szczegółowo

Podstawy Informatyki. Sprawność algorytmów

Podstawy Informatyki. Sprawność algorytmów Podstawy Informatyki Sprawność algorytmów Sprawność algorytmów Kryteria oceny oszczędności Miara złożoności rozmiaru pamięci (złożoność pamięciowa): Liczba zmiennych + liczba i rozmiar struktur danych

Bardziej szczegółowo

Sortowanie - wybrane algorytmy

Sortowanie - wybrane algorytmy 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

Bardziej szczegółowo

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je. Problem porządkowania zwanego również sortowaniem jest jednym z najważniejszych i najpopularniejszych zagadnień informatycznych. Dane: Liczba naturalna n i ciąg n liczb x 1, x 2,, x n. Wynik: Uporządkowanie

Bardziej szczegółowo

Analiza algorytmów zadania podstawowe

Analiza algorytmów zadania podstawowe Analiza algorytmów zadania podstawowe Zadanie 1 Zliczanie Zliczaj(n) 1 r 0 2 for i 1 to n 1 3 do for j i + 1 to n 4 do for k 1 to j 5 do r r + 1 6 return r 0 Jaka wartość zostanie zwrócona przez powyższą

Bardziej szczegółowo

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

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

Bardziej szczegółowo

Zaawansowane algorytmy i struktury danych

Zaawansowane algorytmy i struktury danych Zaawansowane algorytmy i struktury danych u dr Barbary Marszał-Paszek Opracowanie pytań praktycznych z egzaminów. Strona 1 z 12 Pytania praktyczne z kolokwium zaliczeniowego z 19 czerwca 2014 (studia dzienne)

Bardziej szczegółowo

Algorytm selekcji Hoare a. Łukasz Miemus

Algorytm selekcji Hoare a. Łukasz Miemus Algorytm selekcji Hoare a Łukasz Miemus 1 lutego 2006 Rozdział 1 O algorytmie 1.1 Problem Mamy tablicę A[N] różnych elementów i zmienną int K, takie że 1 K N. Oczekiwane rozwiązanie to określenie K-tego

Bardziej szczegółowo

Zasady analizy algorytmów

Zasady analizy algorytmów Zasady analizy algorytmów A więc dziś w programie: - Kilka ważnych definicji i opisów formalnych - Złożoność: czasowa i pamięciowa - Kategorie problemów - Jakieś przykłady Problem: Zadanie możliwe do rozwiązania

Bardziej szczegółowo

Sortowanie. LABORKA Piotr Ciskowski

Sortowanie. LABORKA Piotr Ciskowski Sortowanie LABORKA Piotr Ciskowski main Zaimplementuj metody sortowania przedstawione w następnych zadaniach Dla każdej metody osobna funkcja Nagłówek funkcji wg uznania ale wszystkie razem powinny być

Bardziej szczegółowo

Sortowanie bąbelkowe

Sortowanie bąbelkowe 1/98 Sortowanie bąbelkowe (Bubble sort) prosty i nieefektywny algorytm sortowania wielokrotnie przeglądamy listę elementów, porównując dwa sąsiadujące i zamieniając je miejscami, jeśli znajdują się w złym

Bardziej szczegółowo

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie:

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie: Rekurencje Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie: T(n) = Θ(1) (dla n = 1) T(n) = 2 T(n/2) + Θ(n) (dla n

Bardziej szczegółowo

Programowanie w VB Proste algorytmy sortowania

Programowanie w VB Proste algorytmy sortowania Programowanie w VB Proste algorytmy sortowania Sortowanie bąbelkowe Algorytm sortowania bąbelkowego polega na porównywaniu par elementów leżących obok siebie i, jeśli jest to potrzebne, zmienianiu ich

Bardziej szczegółowo

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2014/2015. Drzewa BST c.d., równoważenie drzew, kopce.

ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 2014/2015. Drzewa BST c.d., równoważenie drzew, kopce. POLITECHNIKA WARSZAWSKA Instytut Automatyki i Robotyki ZASADY PROGRAMOWANIA KOMPUTERÓW ZAP zima 204/205 Język programowania: Środowisko programistyczne: C/C++ Qt Wykład 2 : Drzewa BST c.d., równoważenie

Bardziej szczegółowo

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

Złożoność obliczeniowa zadania, zestaw 2 Złożoność obliczeniowa zadania, zestaw 2 Określanie złożoności obliczeniowej algorytmów, obliczanie pesymistycznej i oczekiwanej złożoności obliczeniowej 1. Dana jest tablica jednowymiarowa A o rozmiarze

Bardziej szczegółowo

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5. Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5. Schemat Hornera. Wyjaśnienie: Zadanie 1. Pozycyjne reprezentacje

Bardziej szczegółowo

Algorytmy sortujące i wyszukujące

Algorytmy sortujące i wyszukujące Algorytmy sortujące i wyszukujące Zadaniem algorytmów sortujących jest ułożenie elementów danego zbioru w ściśle określonej kolejności. Najczęściej wykorzystywany jest porządek numeryczny lub leksykograficzny.

Bardziej szczegółowo

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

Za pierwszy niebanalny algorytm uważa się algorytm Euklidesa wyszukiwanie NWD dwóch liczb (400 a 300 rok przed narodzeniem Chrystusa). Algorytmy definicja, cechy, złożoność. Algorytmy napotykamy wszędzie, gdziekolwiek się zwrócimy. Rządzą one wieloma codziennymi czynnościami, jak np. wymiana przedziurawionej dętki, montowanie szafy z

Bardziej szczegółowo

Znaleźć wzór ogólny i zbadać istnienie granicy ciągu określonego rekurencyjnie:

Znaleźć wzór ogólny i zbadać istnienie granicy ciągu określonego rekurencyjnie: Ciągi rekurencyjne Zadanie 1 Znaleźć wzór ogólny i zbadać istnienie granicy ciągu określonego rekurencyjnie: w dwóch przypadkach: dla i, oraz dla i. Wskazówka Należy poszukiwać rozwiązania w postaci, gdzie

Bardziej szczegółowo

Wstęp do programowania

Wstęp do programowania Wstęp do programowania Algorytmy na tablicach Paweł Daniluk Wydział Fizyki Jesień 2013 P. Daniluk (Wydział Fizyki) WP w. III Jesień 2013 1 / 23 Dwadzieścia pytań Zasady 1 Osoba 1 wymyśla hasło z ustalonej

Bardziej szczegółowo

Efektywna metoda sortowania sortowanie przez scalanie

Efektywna metoda sortowania sortowanie przez scalanie Efektywna metoda sortowania sortowanie przez scalanie Rekurencja Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Metoda dziel i zwycięŝaj Dzielimy

Bardziej szczegółowo

Wstęp do programowania

Wstęp do programowania Wstęp do programowania Rekurencja, metoda dziel i zwyciężaj Paweł Daniluk Wydział Fizyki Jesień 2014 P. Daniluk(Wydział Fizyki) WP w. VIII Jesień 2014 1 / 27 Rekurencja Recursion See Recursion. P. Daniluk(Wydział

Bardziej szczegółowo

Temat 7. Najlżejsze i najcięższe algorytmy sortowania

Temat 7. Najlżejsze i najcięższe algorytmy sortowania Temat 7 Najlżejsze i najcięższe algorytmy sortowania Streszczenie Komputery są często używane porządkowania różnych danych, na przykład nazwisk (w porządku alfabetycznym), terminów spotkań lub e-maili

Bardziej szczegółowo

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

Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to Złożoność obliczeniowa algorytmu ilość zasobów komputera jakiej potrzebuje dany algorytm. Pojęcie to wprowadzili J. Hartmanis i R. Stearns. Najczęściej przez zasób rozumie się czas oraz pamięć dlatego

Bardziej szczegółowo

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 9 Rekurencja

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 9 Rekurencja Podstawy Informatyki Inżynieria Ciepła, I rok Wykład 9 Rekurencja Rekurencja z łacińskiego oznacza to przybiec z powrotem - osiągniesz rzecz wielką, jeśli zawrócisz po to, by osiągnąć rzeczy małe Przykład:

Bardziej szczegółowo

Sortowanie. Bartman Jacek Algorytmy i struktury

Sortowanie. Bartman Jacek Algorytmy i struktury Sortowanie Bartman Jacek jbartman@univ.rzeszow.pl Algorytmy i struktury danych Sortowanie przez proste wstawianie przykład 41 56 17 39 88 24 03 72 41 56 17 39 88 24 03 72 17 41 56 39 88 24 03 72 17 39

Bardziej szczegółowo

Wykład 2. Drzewa zbalansowane AVL i 2-3-4

Wykład 2. Drzewa zbalansowane AVL i 2-3-4 Wykład Drzewa zbalansowane AVL i -3-4 Drzewa AVL Wprowadzenie Drzewa AVL Definicja drzewa AVL Operacje wstawiania i usuwania Złożoność obliczeniowa Drzewa -3-4 Definicja drzewa -3-4 Operacje wstawiania

Bardziej szczegółowo

INFORMATYKA SORTOWANIE DANYCH.

INFORMATYKA SORTOWANIE DANYCH. INFORMATYKA SORTOWANIE DANYCH http://www.infoceram.agh.edu.pl SORTOWANIE Jest to proces ustawiania zbioru obiektów w określonym porządku. Sortowanie stosowane jest w celu ułatwienia późniejszego wyszukania

Bardziej szczegółowo

Wyszukiwanie binarne

Wyszukiwanie binarne Wyszukiwanie binarne Wyszukiwanie binarne to technika pozwalająca na przeszukanie jakiegoś posortowanego zbioru danych w czasie logarytmicznie zależnym od jego wielkości (co to dokładnie znaczy dowiecie

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

Matematyka dyskretna. Andrzej Łachwa, UJ, /15 Matematyka dyskretna Andrzej Łachwa, UJ, 2015 andrzej.lachwa@uj.edu.pl 3/15 Indukcja matematyczna Poprawność indukcji matematycznej wynika z dobrego uporządkowania liczb naturalnych, czyli z następującej

Bardziej szczegółowo

Laboratorium nr 7 Sortowanie

Laboratorium nr 7 Sortowanie Laboratorium nr 7 Sortowanie 1. Sortowanie bąbelkowe (BbS) 2. Sortowanie przez wstawianie (IS) 3. Sortowanie przez wybieranie (SS) Materiały Wyróżniamy następujące metody sortowania: 1. Przez prostą zamianę

Bardziej szczegółowo

Algorytmy i Struktury Danych, 2. ćwiczenia

Algorytmy i Struktury Danych, 2. ćwiczenia Algorytmy i Struktury Danych, 2. ćwiczenia 2017-10-13 Spis treści 1 Optymalne sortowanie 5 ciu elementów 1 2 Sortowanie metodą Shella 2 3 Przesunięcie cykliczne tablicy 3 4 Scalanie w miejscu dla ciągów

Bardziej szczegółowo

Indukcja matematyczna

Indukcja matematyczna Indukcja matematyczna 1 Zasada indukcji Rozpatrzmy najpierw następujący przykład. Przykład 1 Oblicz sumę 1 + + 5 +... + (n 1). Dyskusja. Widzimy że dla n = 1 ostatnim składnikiem powyższej sumy jest n

Bardziej szczegółowo

Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa

Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa Łukasz Przywarty 171018 Data utworzenia: 24.03.2010r. Mariusz Kacała 171058 Prowadzący: prof. dr hab. inż. Adam Janiak oraz dr inż. Tomiasz Krysiak Zadanie projektowe 1: Struktury danych i złożoność obliczeniowa

Bardziej szczegółowo

Uwaga: Funkcja zamień(a[j],a[j+s]) zamienia miejscami wartości A[j] oraz A[j+s].

Uwaga: Funkcja zamień(a[j],a[j+s]) zamienia miejscami wartości A[j] oraz A[j+s]. Zadanie 1. Wiązka zadań Od szczegółu do ogółu Rozważmy następujący algorytm: Dane: Algorytm 1: k liczba naturalna, A[1...2 k ] tablica liczb całkowitych. n 1 dla i=1,2,,k wykonuj n 2n s 1 dopóki s

Bardziej szczegółowo

Matematyczne Podstawy Informatyki

Matematyczne Podstawy Informatyki Matematyczne Podstawy Informatyki dr inż. Andrzej Grosser Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska Rok akademicki 2013/2014 Algorytm 1. Termin algorytm jest używany w informatyce

Bardziej szczegółowo

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne Algorytmy i struktury danych Wykład VIII Elementarne techniki algorytmiczne Co dziś? Algorytmy zachłanne (greedyalgorithms) 2 Tytułem przypomnienia metoda dziel i zwyciężaj. Problem można podzielić na

Bardziej szczegółowo

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

Złożoność algorytmów. Wstęp do Informatyki Złożoność algorytmów Złożoność pamięciowa - liczba i rozmiar struktur danych wykorzystywanych w algorytmie Złożoność czasowa - liczba operacji elementarnych wykonywanych w trakcie przebiegu algorytmu Złożoność

Bardziej szczegółowo

Poprawność semantyczna

Poprawność semantyczna Poprawność składniowa Poprawność semantyczna Poprawność algorytmu Wypisywanie zdań z języka poprawnych składniowo Poprawne wartościowanie zdań języka, np. w języku programowania skutki wystąpienia wyróżnionych

Bardziej szczegółowo

Analiza algorytmów zadania podstawowe

Analiza algorytmów zadania podstawowe Analiza algorytmów zadania podstawowe 15 stycznia 2019 Zadanie 1 Zliczanie Zliczaj(n) 1 r 0 2 for i 1 to n 1 3 do for j i + 1 to n 4 do for k 1 to j 5 do r r + 1 6 return r P Jaka wartość zostanie zwrócona

Bardziej szczegółowo

znalezienia elementu w zbiorze, gdy w nim jest; dołączenia nowego elementu w odpowiednie miejsce, aby zbiór pozostał nadal uporządkowany.

znalezienia elementu w zbiorze, gdy w nim jest; dołączenia nowego elementu w odpowiednie miejsce, aby zbiór pozostał nadal uporządkowany. Przedstawiamy algorytmy porządkowania dowolnej liczby elementów, którymi mogą być liczby, jak również elementy o bardziej złożonej postaci (takie jak słowa i daty). Porządkowanie, nazywane również często

Bardziej szczegółowo

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych.

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych. Jarosław Wróblewski Matematyka dla Myślących, 008/09. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych. 15 listopada 008 r. Uwaga: Przyjmujemy,

Bardziej szczegółowo

Algorytmy i Struktury Danych. (c) Marcin Sydow. Sortowanie Selection Sort Insertion Sort Merge Sort. Sortowanie 1. Listy dowiązaniowe.

Algorytmy i Struktury Danych. (c) Marcin Sydow. Sortowanie Selection Sort Insertion Sort Merge Sort. Sortowanie 1. Listy dowiązaniowe. 1 Tematy wykładu: problem sortowania sortowanie przez wybór (SelectionSort) sortowanie przez wstawianie (InsertionSort) sortowanie przez złaczanie (MergeSort) struktura danych list dowiązaniowych Input:

Bardziej szczegółowo

Zaawansowane algorytmy. Wojciech Horzelski

Zaawansowane algorytmy. Wojciech Horzelski Zaawansowane algorytmy Wojciech Horzelski 1 Organizacja Wykład: poniedziałek 8 15-10 Aula Ćwiczenia: Każdy student musi realizować projekty (treść podawana na wykładzie) : Ilość projektów : 5-7 Na realizację

Bardziej szczegółowo

Algorytmy i Struktury Danych.

Algorytmy i Struktury Danych. Algorytmy i Struktury Danych. Metoda Dziel i zwyciężaj. Problem Sortowania, cd. Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 2 Bożena Woźna-Szcześniak (AJD) Algorytmy

Bardziej szczegółowo

Zajęcia nr. 3 notatki

Zajęcia nr. 3 notatki Zajęcia nr. 3 notatki 22 kwietnia 2005 1 Funkcje liczbowe wprowadzenie Istnieje nieskończenie wiele funkcji w matematyce. W dodaktu nie wszystkie są liczbowe. Rozpatruje się funkcje które pobierają argumenty

Bardziej szczegółowo

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe Algorytmy sortujące sortowanie kubełkowe, sortowanie grzebieniowe Sortowanie kubełkowe (bucket sort) Jest to jeden z najbardziej popularnych algorytmów sortowania. Został wynaleziony w 1956 r. przez E.J.

Bardziej szczegółowo

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał REKURENCJA W JĘZYKU HASKELL Autor: Walczak Michał CZYM JEST REKURENCJA? Rekurencja zwana rekursją, polega na wywołaniu przez funkcję samej siebie. Algorytmy rekurencyjne zastępują w pewnym sensie iteracje.

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /10

Matematyka dyskretna. Andrzej Łachwa, UJ, /10 Matematyka dyskretna Andrzej Łachwa, UJ, 2018 andrzej.lachwa@uj.edu.pl 10/10 Podziały i liczby Stirlinga Liczba Stirlinga dla cykli (często nazywana liczbą Stirlinga pierwszego rodzaju) to liczba permutacji

Bardziej szczegółowo

Algorytmy w teorii liczb

Algorytmy w teorii liczb Łukasz Kowalik, ASD 2004: Algorytmy w teorii liczb 1 Algorytmy w teorii liczb Teoria liczb jest działem matemtyki dotyczącym własności liczb naturalnych. Rozważa się zagadnienia związane z liczbami pierwszymi,

Bardziej szczegółowo

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Sortowanie danych. Jolanta Bachan. Podstawy programowania Sortowanie danych Podstawy programowania 2013-06-06 Sortowanie przez wybieranie 9 9 9 9 9 9 10 7 7 7 7 7 10 9 1 3 3 4 10 7 7 10 10 10 10 4 4 4 4 4 4 3 3 3 3 2 2 2 2 2 2 2 3 1 1 1 1 1 1 Gurbiel et al. 2000

Bardziej szczegółowo

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak Indukcja Materiały pomocnicze do wykładu wykładowca: dr Magdalena Kacprzak Charakteryzacja zbioru liczb naturalnych Arytmetyka liczb naturalnych Jedną z najważniejszych teorii matematycznych jest arytmetyka

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, a/15

Matematyka dyskretna. Andrzej Łachwa, UJ, a/15 Matematyka dyskretna Andrzej Łachwa, UJ, 2017 andrzej.lachwa@uj.edu.pl 3a/15 Indukcja matematyczna Zasada Minimum Dowolny niepusty podzbiór S zbioru liczb naturalnych ma w sobie liczbę najmniejszą. Zasada

Bardziej szczegółowo

Algorytmy i Struktury Danych.

Algorytmy i Struktury Danych. Algorytmy i Struktury Danych. Organizacja wykładu. Problem Sortowania. Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 1 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury

Bardziej szczegółowo

Rekurencja. Przykład. Rozważmy ciąg

Rekurencja. Przykład. Rozważmy ciąg Rekurencja Definicje rekurencyjne Definicja: Mówimy, iż ciąg jest zdefiniowany rekurencyjnie, jeżeli: (P) Określony jest pewien skończony zbiór wyrazów tego ciągu, zwykle jest to pierwszy wyraz tego ciągu

Bardziej szczegółowo

CIĄGI wiadomości podstawowe

CIĄGI wiadomości podstawowe 1 CIĄGI wiadomości podstawowe Jak głosi definicja ciąg liczbowy to funkcja, której dziedziną są liczby naturalne dodatnie (w zadaniach oznacza się to najczęściej n 1) a wartościami tej funkcji są wszystkie

Bardziej szczegółowo

TEORETYCZNE PODSTAWY INFORMATYKI

TEORETYCZNE PODSTAWY INFORMATYKI 1 TEORETYCZNE PODSTAWY INFORMATYKI WFAiS UJ, Informatyka Stosowana I rok studiów, I stopień Wykład 2 2 Problemy algorytmiczne Klasy problemów algorytmicznych Liczby Fibonacciego Przeszukiwanie tablic Największy

Bardziej szczegółowo

Algorytmy i Struktury Danych

Algorytmy i Struktury Danych Algorytmy i Struktury Danych Kopce Bożena Woźna-Szcześniak bwozna@gmail.com Jan Długosz University, Poland Wykład 11 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych Wykład 11 1 / 69 Plan wykładu

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

Matematyka dyskretna. Andrzej Łachwa, UJ, /14 Matematyka dyskretna Andrzej Łachwa, UJ, 2016 andrzej.lachwa@uj.edu.pl 6/14 Sumy Oto dwie konwencje zapisu skończonych sum wyrazów: (notacja Sigma, Fourier, 1820) Czasami stosowana jest ogólniejsza notacja,

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /10

Matematyka dyskretna. Andrzej Łachwa, UJ, /10 Matematyka dyskretna Andrzej Łachwa, UJ, 2018 andrzej.lachwa@uj.edu.pl 3/10 indukcja matematyczna Poprawność indukcji matematycznej wynika z dobrego uporządkowania liczb naturalnych, czyli z następującej

Bardziej szczegółowo

Sortowanie przez wstawianie Insertion Sort

Sortowanie przez wstawianie Insertion Sort Sortowanie przez wstawianie Insertion Sort Algorytm sortowania przez wstawianie można porównać do sposobu układania kart pobieranych z talii. Najpierw bierzemy pierwszą kartę. Następnie pobieramy kolejne,

Bardziej szczegółowo

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

Wykład 4. Określimy teraz pewną ważną klasę pierścieni. Wykład 4 Określimy teraz pewną ważną klasę pierścieni. Twierdzenie 1 Niech m, n Z. Jeśli n > 0 to istnieje dokładnie jedna para licz q, r, że: m = qn + r, 0 r < n. Liczbę r nazywamy resztą z dzielenia

Bardziej szczegółowo

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel Wstęp do programowania Dziel i rządź Piotr Chrząstowski-Wachtel Divide et impera Starożytni Rzymianie znali tę zasadę Łatwiej się rządzi, jeśli poddani są podzieleni Nie chodziło im jednak bynajmniej o

Bardziej szczegółowo

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego.

Kolejka priorytetowa. Często rozważa się kolejki priorytetowe, w których poszukuje się elementu minimalnego zamiast maksymalnego. Kolejki Kolejka priorytetowa Kolejka priorytetowa (ang. priority queue) to struktura danych pozwalająca efektywnie realizować następujące operacje na zbiorze dynamicznym, którego elementy pochodzą z określonego

Bardziej szczegółowo

Przykładami ciągów, które Czytelnik dobrze zna (a jeśli nie, to niniejszym poznaje), jest ciąg arytmetyczny:

Przykładami ciągów, które Czytelnik dobrze zna (a jeśli nie, to niniejszym poznaje), jest ciąg arytmetyczny: Podstawowe definicje Definicja ciągu Ciągiem nazywamy funkcję na zbiorze liczb naturalnych, tzn. przyporządkowanie każdej liczbie naturalnej jakiejś liczby rzeczywistej. (Mówimy wtedy o ciągu o wyrazach

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /14

Matematyka dyskretna. Andrzej Łachwa, UJ, /14 Matematyka dyskretna Andrzej Łachwa, UJ, 2019 andrzej.lachwa@uj.edu.pl 4/14 Indukcja matematyczna Poprawność indukcji matematycznej wynika z dobrego uporządkowania liczb naturalnych, czyli z następującej

Bardziej szczegółowo

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0, 2 Arytmetyka Niech b = d r d r 1 d 1 d 0 będzie zapisem liczby w systemie dwójkowym Zamiana zapisu liczby b na system dziesiętny odbywa się poprzez wykonanie dodawania d r 2 r + d r 1 2 r 1 d 1 2 1 + d

Bardziej szczegółowo

Algorytmy i struktury danych

Algorytmy i struktury danych Algorytmy i struktury danych Zaawansowane algorytmy sortowania Witold Marańda maranda@dmcs.p.lodz.pl 1 Sortowanie za pomocą malejących przyrostów metoda Shella Metoda jest rozwinięciem metody sortowania

Bardziej szczegółowo

3. Macierze i Układy Równań Liniowych

3. Macierze i Układy Równań Liniowych 3. Macierze i Układy Równań Liniowych Rozważamy równanie macierzowe z końcówki ostatniego wykładu ( ) 3 1 X = 4 1 ( ) 2 5 Podstawiając X = ( ) x y i wymnażając, otrzymujemy układ 2 równań liniowych 3x

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

Matematyka dyskretna. Andrzej Łachwa, UJ, /15 Matematyka dyskretna Andrzej Łachwa, UJ, 2013 andrzej.lachwa@uj.edu.pl 6/15 Sumy Oto dwie konwencje zapisu skończonych sum wyrazów: (notacja Sigma, Fourier, 1820) Czasami stosowana jest ogólniejsza notacja,

Bardziej szczegółowo

O rekurencji i nie tylko

O rekurencji i nie tylko O rekurencji i nie tylko dr Krzysztof Bryś Wydział Matematyki i Nauk Informacyjnych Politechnika Warszawska 10 grudnia 2011 Intuicyjnie: rekurencja sprowadzenie rozwiązania danego problemu do rozwiązania

Bardziej szczegółowo

Przykładowe zadania z teorii liczb

Przykładowe zadania z teorii liczb Przykładowe zadania z teorii liczb I. Podzielność liczb całkowitych. Liczba a = 346 przy dzieleniu przez pewną liczbę dodatnią całkowitą b daje iloraz k = 85 i resztę r. Znaleźć dzielnik b oraz resztę

Bardziej szczegółowo

Algorytmy i struktury danych. Wykład 4

Algorytmy i struktury danych. Wykład 4 Wykład 4 Różne algorytmy - obliczenia 1. Obliczanie wartości wielomianu 2. Szybkie potęgowanie 3. Algorytm Euklidesa, liczby pierwsze, faktoryzacja liczby naturalnej 2017-11-24 Algorytmy i struktury danych

Bardziej szczegółowo

FUNKCJA LINIOWA - WYKRES

FUNKCJA LINIOWA - WYKRES FUNKCJA LINIOWA - WYKRES Wzór funkcji liniowej (Postać kierunkowa) Funkcja liniowa jest podstawowym typem funkcji. Jest to funkcja o wzorze: y = ax + b a i b to współczynniki funkcji, które mają wartości

Bardziej szczegółowo

Zadanie 3 Oblicz jeżeli wiadomo, że liczby 8 2,, 1, , tworzą ciąg arytmetyczny. Wyznacz różnicę ciągu. Rozwiązanie:

Zadanie 3 Oblicz jeżeli wiadomo, że liczby 8 2,, 1, , tworzą ciąg arytmetyczny. Wyznacz różnicę ciągu. Rozwiązanie: Zadanie 3 Oblicz jeżeli wiadomo, że liczby 8 2,, 1, 6 11 6 11, tworzą ciąg arytmetyczny. Wyznacz różnicę ciągu. Uprośćmy najpierw liczby dane w treści zadania: 8 2, 2 2 2 2 2 2 6 11 6 11 6 11 26 11 6 11

Bardziej szczegółowo

ALGORYTMY I STRUKTURY DANYCH

ALGORYTMY I STRUKTURY DANYCH ALGORYTMY I STRUKTURY DANYCH Temat : Drzewa zrównoważone, sortowanie drzewiaste Wykładowca: dr inż. Zbigniew TARAPATA e-mail: Zbigniew.Tarapata@isi.wat.edu.pl http://www.tarapata.strefa.pl/p_algorytmy_i_struktury_danych/

Bardziej szczegółowo

Programowanie dynamiczne

Programowanie dynamiczne Programowanie dynamiczne Patryk Żywica 5 maja 2008 1 Spis treści 1 Problem wydawania reszty 3 1.1 Sformułowanie problemu...................... 3 1.2 Algorytm.............................. 3 1.2.1 Prosty

Bardziej szczegółowo

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze,

Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze, Oznaczenia: Jeśli czas działania algorytmu zależy nie tylko od rozmiaru danych wejściowych i przyjmuje różne wartości dla różnych danych o tym samym rozmiarze, to interesuje nas złożoność obliczeniowa

Bardziej szczegółowo

Matematyka dyskretna. Andrzej Łachwa, UJ, /15

Matematyka dyskretna. Andrzej Łachwa, UJ, /15 Matematyka dyskretna Andrzej Łachwa, UJ, 2014 andrzej.lachwa@uj.edu.pl 3/15 Indukcja matematyczna Poprawność indukcji matematycznej wynika z dobrego uporządkowania liczb naturalnych, czyli z następującej

Bardziej szczegółowo

Algorytmy sortujące 1

Algorytmy sortujące 1 Algorytmy sortujące 1 Sortowanie Jeden z najczęściej występujących, rozwiązywanych i stosowanych problemów. Ułożyć elementy listy (przyjmujemy: tablicy) w rosnącym porządku Sortowanie może być oparte na

Bardziej szczegółowo

Wyszukiwanie. Wyszukiwanie binarne

Wyszukiwanie. Wyszukiwanie binarne Wyszukiwanie Wejście: posortowana, n-elementowa tablica liczbowa T oraz liczba p. Wyjście: liczba naturalna, określająca pozycję elementu p w tablicy T, bądź 1, jeŝeli element w tablicy nie występuje.

Bardziej szczegółowo

Jeszcze o algorytmach

Jeszcze o algorytmach Jeszcze o algorytmach Przykłady różnych, podstawowych algorytmów 11.01.2018 M. Rad Plan Powtórka Znajdowanie najmniejszego elementu Segregowanie Poszukiwanie przez połowienie Wstawianie Inne algorytmy

Bardziej szczegółowo

1. A 2. A 3. B 4. B 5. C 6. B 7. B 8. D 9. A 10. D 11. C 12. D 13. B 14. D 15. C 16. C 17. C 18. B 19. D 20. C 21. C 22. D 23. D 24. A 25.

1. A 2. A 3. B 4. B 5. C 6. B 7. B 8. D 9. A 10. D 11. C 12. D 13. B 14. D 15. C 16. C 17. C 18. B 19. D 20. C 21. C 22. D 23. D 24. A 25. 1. A 2. A 3. B 4. B 5. C 6. B 7. B 8. D 9. A 10. D 11. C 12. D 13. B 14. D 15. C 16. C 17. C 18. B 19. D 20. C 21. C 22. D 23. D 24. A 25. A Najłatwiejszym sposobem jest rozpatrzenie wszystkich odpowiedzi

Bardziej szczegółowo

Algorytmy i Struktury Danych. (c) Marcin Sydow. Introduction. QuickSort. Sortowanie 2. Limit. CountSort. RadixSort. Summary

Algorytmy i Struktury Danych. (c) Marcin Sydow. Introduction. QuickSort. Sortowanie 2. Limit. CountSort. RadixSort. Summary Sortowanie 2 Zawartość wykładu: Własność stabilności algorytmów sortujących algorytm sortowania szybkiego () czy można sortować szybciej niż ze złożonością Θ(n log(n))? algorytm sortowania przez zliczanie

Bardziej szczegółowo

Algorytmy i struktury danych. Wykład 4 Tablice nieporządkowane i uporządkowane

Algorytmy i struktury danych. Wykład 4 Tablice nieporządkowane i uporządkowane Algorytmy i struktury danych Wykład 4 Tablice nieporządkowane i uporządkowane Tablice uporządkowane Szukanie binarne Szukanie interpolacyjne Tablice uporządkowane Szukanie binarne O(log N) Szukanie interpolacyjne

Bardziej szczegółowo