Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11...

225
1 Syllabus Wprowadzenie Poprawność algorytmów (analiza algorytmów) Sortowanie Elementarne struktury danych Wyszukiwanie Zaawansowane struktury danych Programowanie dynamiczne

Transcript of Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11...

Page 1: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

1

Syllabus

Wprowadzenie

Poprawność algorytmów (analiza algorytmów)

Sortowanie

Elementarne struktury danych

Wyszukiwanie

Zaawansowane struktury danych

Programowanie dynamiczne

Page 2: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

2

Literatura

T. Cormen, Ch. Lieserson, R. Rivest, Wprowadzenie do Algorytmów, WNT, 1997

R. Sedgewick, Algorytmy w C++, RM, 1999

N. Wirth, Algorytmy + struktury danych = programy, WNT, 2001

Page 3: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

3

O co w tym wszystkim chodzi?

Rozwiązywanie problemów:

– Układanie planu zajęć

– Balansowanie własnego budżet

– Symulacja lotu samolotem

– Prognoza pogody

Dla rozwiązania problemów potrzebujemy procedur, recept, przepisów –

inaczej mówiąc algorytmów

Page 4: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

4

Historia

Nazwa pochodzi od perskiego matematyka Muhammeda ibn Musa

Alchwarizmiego (w łacińskiej wersji Algorismus) – IX w n.e.

Pierwszy dobrze opisany algorytm – algorytm Euklidesa znajdowania

największego wspólnego podzielnika, 400-300 p.n.e.

XIX w. – Charles Babbage, Ada Lovelace.

XX w. – Alan Turing, Alonzo Church, John von Neumann

Page 5: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

5

Struktury danych i algorytmy

Algorytm – metoda, zestaw działań (instrukcji) potrzebnych do

rozwiązania problemu

Program – implementacja algorytmu w jakimś języku programowania

Struktura danych – organizacja danych niezbędna dla rozwiązania

problemu (metody dostępu etc.)

Page 6: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

6

Ogólne spojrzenie

Cele algorytmiczne:- poprawność, - efektywność,

Cele implementacji:- zwięzłość- możliwość powtórnego wykorzystania

Wykorzystanie komputera:

Projektowanie programów (algorytmy, struktury danych)

Pisanie programów (kodowanie)

Weryfikacja programów (testowanie)

Page 7: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

7

Problemy algorytmiczne

Ilość instancji danych spełniających

specyfikację wejścia może być nieskończona, np.:

posortowana niemalejąco sekwencja liczb naturalnych, o skończonej długości:

1, 20, 908, 909, 100000, 1000000000.

3, 44, 211, 222, 433.

3.

Specyfikacja wejścia

?Specyfikacja wyjścia, jako funkcji wejścia

Page 8: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

8

Rozwiązanie problemu

– Algorytm opisuje działania, które mają zostać przeprowadzone na danych

– Może istnieć wiele algorytmów rozwiązujących ten sam problem

Instancja wejściowa (dane), odpowiadająca specyfikacji

algorytm Wyniki odpowiadające danym wejściowym

Page 9: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

9

Definicja algorytmu

Algorytmem nazywamy skończoną sekwencję jednoznacznych

instrukcji pozwalających na rozwiązanie problemu, tj. na

uzyskanie pożądanego wyjścia dla każdego legalnego wejścia.

Własności algorytmów:

– określoność

– skończoność

– poprawność

– ogólność

– dokładność

Page 10: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

10

Przykład 1: poszukiwanie

Wejście:• uporządkowany niemalejąco ciąg n

(n >0) liczb

• liczba

a1, a2, a3,….,an; qj

Wyjście:• indeks (pozycja)

odnalezionej wartości lub

NIL

2 5 4 10 11; 5 2

2 5 4 10 11; 9 NIL

Page 11: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

11

Przykład 1: poszukiwanie liniowe

INPUT: A[1..n] – tablica liczb, q – liczba całkowita.

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

j←←←←1while j ≤≤≤≤ n and A[j] ≠≠≠≠ q

do j++if j ≤≤≤≤ n then return jelse return NIL

INPUT: A[1..n] – tablica liczb, q – liczba całkowita.

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

j←←←←1while j ≤≤≤≤ n and A[j] ≠≠≠≠ q

do j++if j ≤≤≤≤ n then return jelse return NIL

Algorytm wykorzystuje metodę siłową (brute-force) – przegląda kolejno elementy tablicy.

Kod napisany jest w jednoznacznym pseudojęzyku (pseudokodzie). Wejście (INPUT) i wyjście (OUTPUT) zostały jasno określone.

Page 12: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

12

Pseudokod

Zbliżony do Ady, C, Javy czy innego języka programowania:

– struktury sterujące (if … then … else, pętle while i for)

– przypisanie (←)

– dostęp do elementów tablicy: A[i]

– dla typów złożonych (record lub object) dostęp do pól: A.b

– zmienna reprezentująca tablicę czy obiekt jest traktowana jak wskaźnik do

tej struktury (podobnie, jak w C).

Page 13: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

13

Warunki początkowe i końcowe (precondition, postcondition)

Ważne jest sprecyzowanie warunków początkowego i końcowego dla

algorytmu:

– INPUT: określenie jakie dane algorytm powinien dostać na wejściu

– OUTPUT: określenie co algorytm powinien wyprodukować. Powinna zostać

przewidziana obsługa specjalnych przypadków danych wejściowych

Page 14: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

14

Sort

Przykład 2: sortowanie

Wejścieciąg n liczb

a1, a2, a3,….,anb1,b2,b3,….,bn

WyjściePermutacja wejściowego

ciągu

2 5 4 10 7 2 4 5 7 10

poprawność wyjścia:Dla każdego wejścia algorytm po zakończeniu działania powinien dać jako wynik b1, b2, …, bn takie, że:

• b1 < b2 < b3 < …. < bn

• b1, b2, b3, …., bn jest permutacją a1, a2, a3,….,an

poprawność wyjścia:Dla każdego wejścia algorytm po zakończeniu działania powinien dać jako wynik b1, b2, …, bn takie, że:

• b1 < b2 < b3 < …. < bn

• b1, b2, b3, …., bn jest permutacją a1, a2, a3,….,an

Page 15: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

15

Sortowanie przez wstawianie (Insertion Sort)

A1 nj

3 6 84 9 7 2 5 1

i

Strategia

• zaczynamy od “pustej ręki”

• wkładamy kartę we właściwe

miejsce kart poprzednio już

posortowane

• kontynuujemy takie postępowanie

aż wszystkie karty zostaną

wstawione

Strategia

• zaczynamy od “pustej ręki”

• wkładamy kartę we właściwe

miejsce kart poprzednio już

posortowane

• kontynuujemy takie postępowanie

aż wszystkie karty zostaną

wstawione

INPUT: A[1..n] – tablica liczb całkowitych

OUTPUT: permutacja A taka, że A[1]≤A[2]≤ …≤A[n]

for j←2 to n

do key←A[j]

wstaw A[j] do posortowanej

sekwencji A[1..j-1]i←j-1

while i>0 and A[i]>key

do A[i+1]←A[i]

i--

A[i+1]←key

INPUT: A[1..n] – tablica liczb całkowitych

OUTPUT: permutacja A taka, że A[1]≤A[2]≤ …≤A[n]

for j←2 to n

do key←A[j]

wstaw A[j] do posortowanej

sekwencji A[1..j-1]i←j-1

while i>0 and A[i]>key

do A[i+1]←A[i]

i--

A[i+1]←key

Page 16: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

16

Analiza algorytmów

Efektywność:

– Czas działania

– Wykorzystanie pamięci

Efektywność jako funkcja rozmiaru wejścia:

– Ilość danych wejściowych (liczb, punktów, itp.)

– Ilość bitów w danych wejściowych

Page 17: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

17

Analiza sortowania przez wstawianie

for j←2 to n

do key←A[j]

wstaw A[j] do posortowanej

sekwencji A[1..j-1]i←j-1

while i>0 and A[i]>key

do A[i+1]←A[i]

i--

A[i+1]:=key

czas

c1c20

c3c4c5c6c7

ile razy

n

n-1

n-1

n-1

n-1

2

n

jjt

=∑2( 1)

n

jjt

=−∑

2( 1)

n

jjt

=−∑

Określany czas wykonania jako funkcję rozmiaru wejścia

Page 18: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

18

Przypadki: najlepszy/najgorszy/średni

Najlepszy przypadek: elementy już są posortowane →→→→ tj=1, czas wykonania

liniowy (Cn).

Najgorszy przypadek: elementy posortowane nierosnąco (odwrotnie

posortowane) →→→→ tj=j, czas wykonania kwadratowy (Cn2)

Przypadek „średni” : tj=j/2, czas wykonania kwadratowy (Cn2)

Page 19: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

19

Przypadki: najlepszy/najgorszy/średni

– Dla ustalonego n czas wykonania dla poszczególnych instancji:

1n

2n

3n

4n

5n

6n

Page 20: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

20

Przypadki: najlepszy/najgorszy/średni

– Dla różnych n:

1n

2n

3n

4n

5n

6n

Rozmiar wejścia

Cza

s dzi

ałan

ia

1 2 3 4 5 6 7 8 9 10 11 12 …..

najlepszy przypadek

„średni” przypadek

najgorszy przypadek

Page 21: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

21

Przypadki: najlepszy/najgorszy/średni

Analizę najgorszego przypadku stosuje się zwykle wtedy, kiedy czas działania

jest czynnikiem krytycznym (kontrola lotów, sterowanie podawaniem leków itp.)

Dla pewnych zadań „najgorsze” przypadki mogą występować dość często.

Określenie przypadku „średniego” (analiza probabilistyczna) jest często bardzo

kłopotliwe

Page 22: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

22

Różnice w podejściu?

Czy sortowanie przez wstawianie jest najlepszą strategią dla zadania

sortowania?

Rozważmy alternatywną strategię opartą o zasadę „dziel i zwyciężaj”:

Sortowanie przez łączenie (MergeSort):

– ciąg <4, 1, 3, 9> dzielimy na dwa podciągi

– Sortujemy te podciągi: <4, 1> i <3, 9>

– łączymy wyniki

• Czas wykonania rzędu n log n

Page 23: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

23

Analiza wyszukiwania

INPUT: A[1..n] – tablica liczb całkowitych, q – liczba całkowita

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

j←←←←1

while j ≤≤≤≤ n and A[j] ≠≠≠≠ q

do j++

if j ≤≤≤≤ n then return j

else return NIL

INPUT: A[1..n] – tablica liczb całkowitych, q – liczba całkowita

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

j←←←←1

while j ≤≤≤≤ n and A[j] ≠≠≠≠ q

do j++

if j ≤≤≤≤ n then return j

else return NIL

Najgorszy przypadek: C nŚredni przypadek: C n/2

Page 24: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

24

Poszukiwanie binarne

INPUT: A[1..n] – posortowana tablica liczb całkowitych, q – liczba całkowita.

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

left←←←←1

right←←←←n

do

j←←←←(left+right)/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

INPUT: A[1..n] – posortowana tablica liczb całkowitych, q – liczba całkowita.

OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli ∀∀∀∀j (1≤≤≤≤j≤≤≤≤n): A[j] ≠≠≠≠ q

left←←←←1

right←←←←n

do

j←←←←(left+right)/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

Pomysł: „dziel i zwyciężaj”

Page 25: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

25

Poszukiwanie binarne - analiza

Ile razy wykonywana jest pętla:

– Po każdym przebiegu różnica między left a right zmniejsza się o

połowę

• początkowo n

• pętla kończy się kiedy różnica wynosi 1 lub 0

– Ile razy trzeba połowić n żeby dostać 1?

– lg n – lepiej niż poprzedni algorytm (n)

Page 26: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

26

Poprawność algorytmów

Page 27: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

27

Przegląd

Poprawność algorytmów

Podstawy matematyczne:

– Przyrost funkcji i notacje asymptotyczne

– Sumowanie szeregów

– Indukcja matematyczna

Page 28: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

28

Poprawność algorytmów

Algorytm jest poprawny jeżeli dla każdego legalnego wejścia kończy

swoje działanie i tworzy pożądany wynik.

Automatyczne dowiedzenie poprawności nie możliwe

Istnieją jednak techniki i formalizmy pozwalające na dowodzenie

poprawności algorytmów

Page 29: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

29

Poprawność – praktyczna i całkowita

Praktyczna

Poprawne dane algorytm Wynik

Jeśli ten punkt został

osiągnięty to otrzymaliśmy poprawny wynik

Całkowita poprawność

Poprawne dane algorytm Wynik

i otrzymamy poprawny wynik

Zawsze ten punkt zostanie

osiągnięty

Page 30: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

30

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 (Precondition) – stwierdzenia, których prawdziwość

zakładamy przed wykonaniem algorytmu lub podprogramu (INPUT)

Warunki końcowe (Postcondition) – stwierdzenia, które muszą być

prawdziwe po wykonaniu algorytmu lub podprogramu (OUTPUT)

Page 31: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

31

Niezmienniki pętli

Niezmienniki – stwierdzenia prawdziwe za każdym razem kiedy osiągany

jest pewien punkt algorytmu (może to zdarzać się wielokrotnie w czasie

wykonania algorytmu, np. w pętli)

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 kończy działanie niezmiennik daje własność

przydatną do wykazania poprawności algorytmu

Page 32: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

32

Przykład: poszukiwanie binarne (1)

inicjalizacja: left = 1, right = n niezmiennik jest prawdziwy (nie ma elementów w [1..left-1] i [right+1..n] )

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

Chcemy mieć pewność, że jeżeli zwracany jest NIL to wartości q nie ma w tablicy A

niezmiennik: na początku każdego wykonania pętli whileA[i] < q dla każdego i∈[1..left-1] oraz A[i] > q dla każdego i∈[right+1..n]

Page 33: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

33

Przykład: poszukiwanie binarne (2)

zachowanie: jeśli A[j]>q, to A[i] > q dla wszystkich i ∈∈∈∈[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ęść.

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

niezmiennik: na początku każdego wykonania pętli while A[i] < q dla każdego i∈[1..left-1] oraz A[i] > q dla każdego i∈[right+1..n]

Page 34: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

34

Przykład: poszukiwanie binarne (3)

Zakończenie: 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.

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

left←1

right←n

doj←(left+right)/2if A[j]=q then return jelse if A[j]>q then right←j-1else left=j+1

while left<=rightreturn NIL

niezmiennik: na początku każdego wykonania pętli while A[i] < q dla każdego i∈[1..left-1] oraz A[i] > q dla każdego i∈[right+1..n]

Page 35: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

35

Przykład: sortowanie przez wstawianie

niezmiennik: na początku

każdego wykonania pętli for,

A[1…j-1] składa się z

posortowanych elementów

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

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

inicjalizacja: j = 2, niezmiennik jest trywialny, A[1] jest zawsze posortowana

zachowanie: wewnątrz pętli while 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, że cała tablica została posortowana.

Page 36: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

36

Notacje asymptotyczne

Cel: uproszczenie analizy czasy wykonania, zaniedbywanie „szczegółów”,

które mogą wynikać ze specyficznej implementacji czy sprzętu

– “zaokrąglanie” dla liczb: 1,000,001 ≈ 1,000,000

– “zaokrąglanie” dla funkcji: 3n2 ≈ n2

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”)

Page 37: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

37

Notacje asymptotyczne

Notacja O (duże O)

– Asymptotyczne ograniczenie górne

– f(n) = O(g(n)), jeżeli istnieje stała c i n0,

takie, że f(n) ≤≤≤≤ c g(n) dla n ≥ n0

– f(n) i g(n) są nieujemnymi funkcjami

całkowitymi

Korzysta się z niej przy analizie

najgorszego przypadku.

)(nf( )c g n⋅

0n Rozmiar wejścia

Cza

s d

ział

ania

Page 38: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

38

Notacja ΩΩΩΩ (duża ΩΩΩΩ)

– Asymptotyczne ograniczenie dolne

– f(n) = Ω(g(n)) jeśli istnieje stała c i n0,

takie, że c g(n) ≤≤≤≤ f(n) dla n ≥ n0

Opisuje najlepsze możliwe zachowanie się

algorytmu

Rozmiar wejścia

Cza

s d

ział

ania )(nf

( )c g n⋅

0n

Notacje asymptotyczne

Page 39: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

39

Notacje asymptotyczne

Prosta zasada: odrzucamy mniej istotne dla czasu składniki i czynniki

stałe.

– 50 n log n jest O(n log n)

– 7n - 3 jest O(n)

– 8n2 log n + 5n2 + n jest O(n2 log n)

O jest ograniczeniem górnym więc np. (50 n log n) jest typu O(n5), ale

interesuje nas najlepsze możliwe oszacowanie – w tym przypadku jest to

O(n log n)

Page 40: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

40

Notacja ΘΘΘΘ ((((duża ΘΘΘΘ )

– Dokładne oszacowanie asymptotyczne

– f(n) = Θ(g(n)) jeżeli istnieją stałe c1, c2, i

n0, takie, że c1 g(n) ≤≤≤≤ f(n) ≤≤≤≤ c2 g(n) dla

n ≥ n0

f(n) = ΘΘΘΘ(g(n)) wtedy i tylko wtedy,

gdy f(n) = ΟΟΟΟ(g(n)) i f(n) = ΩΩΩΩ(g(n))

Rozmiar wejścia

Cza

s d

ział

ania )(nf

0n

Notacje asymptotyczne

)(ngc ⋅2

)(ngc ⋅1

Page 41: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

41

Notacje asymptotyczne

Istnieją dwie inne notacje asymptotyczne:

– „małe o" – f(n)=o(g(n))

mocniejsze ograniczenie analogiczne do O

• Dla każdego c, musi istnieć n0 , takie, że f(n) ≤≤≤≤ c g(n) dla n ≥ n0

– „mała omega" – f(n)=ω(g(n))

analogicznie dla Ω

Page 42: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

42

Notacje asymptotyczne

Analogie do zależności pomiędzy liczbami:

– f(n) = O(g(n)) ≅ f ≤≤≤≤ g

– f(n) = Ω(g(n)) ≅ f ≥ g

– f(n) = Θ(g(n)) ≅ f = = = = g

– f(n) = o(g(n)) ≅ f < < < < g

– f(n) = ω(g(n)) ≅ f > > > > g

Zwykle zapisujemy: f(n) = O(g(n)) , co formalnie powinno być rozumiane

jako f(n) ∈∈∈∈O(g(n))

Page 43: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

43

Porównanie czasów wykonania

3125192n

2448831n4

4242654777072n2

7826087166666409620n log n

90000001500002500400n

1 godzina1 minuta1 sekunda

Maksymalny rozmiar problemu (n)

Page 44: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

44

Szeregi

Szereg geometryczny

– Dana jest liczba całkowita n0 i rzeczywiste 0< a ≠ 1

– Szereg geometryczny reprezentuje przyrost wykładniczy

Szereg arytmetyczny

– Przyrost kwadratowy

12

0

11 ...

1

nni n

i

aa a a a

a

+

=

−= + + + + =

−∑

0

(1 )1 2 3 ...

2

n

i

n ni n

=

+= + + + + =∑

Page 45: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

45

Czas działania sortowania przez wstawianie jest zdeterminowany przez zagnieżdżone pętlę

Czas wykonania pętli reprezentuje szereg

Sumowanie

2

2( 1) ( )

n

jj O n

=− =∑

for j←2 to n

do key←A[j]

wstaw A[j] do posortowanej

sekwencji A[1..j-1]i←j-1

while i>0 and A[i]>key

do A[i+1]←A[i]

i--

A[i+1]:=key

czas

c1c20

c3c4c5c6c7

ile razy

n

n-1

n-1

n-1

n-1

2

n

jjt

=∑2( 1)

n

jjt

=−∑

2( 1)

n

jjt

=−∑

Page 46: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

46

Dowody indukcyjne

Chcemy pokazać prawdziwość własności P dla wszystkich liczb

całkowitych n ≥≥≥≥ n0

Założenie indukcyjne: dowodzimy prawdziwości P dla n0

Krok indukcyjny: dowodzimy, że z prawdziwości P dla wszystkich k, n0

≤≤≤≤ k ≤≤≤≤ n – 1 wynika prawdziwość P dla n

Przykład:

Założenie ind.1

0

1(1 1)(1)

2i

S i=

+= =∑

1ndla,2

)1n(ni)n(S

n

0i

≥+

==∑=

Page 47: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

47

Dowody indukcyjne

0

1

0 0

2

( 1)( ) for 1 k 1

2

( ) ( 1)

( 1 1) ( 2 )( 1)

2 2

( 1)

2

k

i

n n

i i

k kS k i n

S n i i n S n n

n n n nn n

n n

=

= =

+= = ≤ ≤ −

= = + = − + =

− + − += − + = =

+=

∑ ∑

Krok indukcyjny

dla

Page 48: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

48

Metoda „dziel i zwyciężaj”

Page 49: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

49

Wprowadzenie

Technika konstrukcji algorytmów dziel i zwyciężaj.

przykładowe problemy:

– Wypełnianie planszy

– Poszukiwanie (binarne)

– Sortowanie (sortowanie przez łączenie - merge sort).

Page 50: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

50

Wypełnianie planszy

Zadanie: dysponując klockami

oraz planszą 2nx2n z brakującym polem:

Wypełnić plansze w całości:

Page 51: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

51

Wypełnianie planszy: przypadki trywialne (n = 1)

Przypadek trywialny (n = 1): wypełniamy plansze jednym klockiem:

Idea dla rozwiązania problemu – doprowadzićrozmiar zadania do przypadku trywialnego, który umiemy rozwiązać

Page 52: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

52

Wypełnianie planszy : podział zadania

Oryginalną planszę dzielimy na 4 części

Dostajemy problemy o rozmiarze 2n-1x2n-1

Ale: trzy z nich nie są podobne do oryginalnego (plansze nie mają brakującego pola)!

Page 53: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

53

Wypełnianie planszy : podział zadania

pomysł: umieszczamy jeden klocek w środku planszy i dokonujemy podziału na 4 części

Teraz otrzymujemy 4 plansze o rozmiarach 2n-1x2n-1.

Każda z planszy ma brakujące pole

Page 54: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

54

Wypełnianie planszy : algorytm

INPUT: n – plansza 2nx2n, 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 w środku planszy

podziel planszę na 4 równe części

Niech L1, L2, L3, L4 oznaczają pozycje 4 brakujących pól

Tile(n-1, L1)

Tile(n-1, L2)

Tile(n-1, L3)

Tile(n-1, L4)

INPUT: n – plansza 2nx2n, 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 w środku planszy

podziel planszę na 4 równe części

Niech L1, L2, L3, L4 oznaczają pozycje 4 brakujących pól

Tile(n-1, L1)

Tile(n-1, L2)

Tile(n-1, L3)

Tile(n-1, L4)

Page 55: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

55

Dziel i zwyciężaj

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:

• Podział: Podziel problem na dwa lub więcej rozdzielnych

podproblemów

• Rozwiązanie: Wykorzystaj metodę rekurencyjnie dla rozwiązania tych

podproblemów

• Łączenie: połącz rozwiązania podproblemów tak, aby rozwiązać

oryginalny problem

Page 56: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

56

Wypełnianie planszy : Dziel i zwyciężaj

Wypełnianie jest przykładem algorytmu „dziel i zwyciężaj” :

– w wypadku trywialnym (2x2) – po prostu wypełniamy planszę, lub:

– Dzielimy planszę na 4 mniejsze części (wprowadzając wypełnione miejsce

w rogu, przez umieszczenie centralnie jednego klocka)

– Rozwiązujemy problem rekursywnie stosując tą samą metodę

– Łączymy części umieszczając klocek w środku planszy

Page 57: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

57

Odnaleźć liczbę w posortowanej tablicy:

– Przypadek trywialny – tablica jest jednoelementowa

– Albo dzielimy tablice na dwie równe części i rozwiązujemy zadanie

osobno dla każdej z nich

Poszukiwanie binarne

INPUT: A[1..n] – posortowana niemalejąco tablica liczb, s – liczba.

OUTPUT: indeks j taki, że A[j] = s. NIL, jeśli ∀j (1≤j≤n): A[j] ≠ s

Binary-search(A, p, r, s):

if p = r then

if A[p] = s then return p

else return NIL

q←(p+r)/2

ret ← Binary-search(A, p, q, s)

if ret = NIL then

return Binary-search(A, q+1, r, s)

else return ret

INPUT: A[1..n] – posortowana niemalejąco tablica liczb, s – liczba.

OUTPUT: indeks j taki, że A[j] = s. NIL, jeśli ∀j (1≤j≤n): A[j] ≠ s

Binary-search(A, p, r, s):

if p = r then

if A[p] = s then return p

else return NIL

q←(p+r)/2

ret ← Binary-search(A, p, q, s)

if ret = NIL then

return Binary-search(A, q+1, r, s)

else return ret

Page 58: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

58

Rekurencja

Czas działania algorytmu z odwołaniami rekursywnymi można opisać poprzez

rekurencję

Równanie/nierówność opisująca funkcję poprzez jej wartości dla mniejszego

argumentu

Przykład: poszukiwanie binarne

Po rozwiązaniu daje to złożoność O(n)! – taką samą jak dla metody naiwnej

(1) if 1( )

2 ( / 2) (1) if 1

nT n

T n n

Θ ==

+ Θ >

Page 59: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

59

Poszukiwanie binarne (poprawione)

INPUT: A[1..n] – posortowana niemalejąco tablica liczb, s – liczba.

OUTPUT: indeks j taki, że A[j] = s. NIL, jeśli ∀j (1≤j≤n): A[j] ≠s

Binary-search(A, p, r, s):

if p = r then

if A[p] = s then return p

else return NIL

q←←←←(p+r)/2

if A[q] ≤≤≤≤ s then return Binary-search(A, p, q, s)

else return Binary-search(A, q+1, r, s)

INPUT: A[1..n] – posortowana niemalejąco tablica liczb, s – liczba.

OUTPUT: indeks j taki, że A[j] = s. NIL, jeśli ∀j (1≤j≤n): A[j] ≠s

Binary-search(A, p, r, s):

if p = r then

if A[p] = s then return p

else return NIL

q←←←←(p+r)/2

if A[q] ≤≤≤≤ s then return Binary-search(A, p, q, s)

else return Binary-search(A, q+1, r, s)

T(n) = Θ(n) – nie lepiej niż dla metody siłowej!

Poprawa: rozwiązywać zadanie tylko dla jednej połowy tablicy

Page 60: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

60

Czas działania metody

T(n) = ΘΘΘΘ(lg n) !

(1) if 1( )

( / 2) (1) if 1

nT n

T n n

Θ ==

+ Θ >

Page 61: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

61

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 n/2 elementów, a S2

kolejne 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

Page 62: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

62

Algorytm – Merge Sort

Merge-Sort(A, p, r)

if p < r then

q← (p+r)/2Merge-Sort(A, p, q)

Merge-Sort(A, q+1, r)

Merge(A, p, q, r)

Merge-Sort(A, p, r)

if p < r then

q← (p+r)/2Merge-Sort(A, p, q)

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].

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].

Page 63: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

63

Sortowanie przez łączenie - 1

Page 64: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

64

Sortowanie przez łączenie - 2

Page 65: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

65

Sortowanie przez łączenie - 3

Page 66: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

66

Sortowanie przez łączenie - 4

Page 67: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

67

Sortowanie przez łączenie - 5

Page 68: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

68

Sortowanie przez łączenie - 6

Page 69: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

69

Sortowanie przez łączenie - 7

Page 70: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

70

Sortowanie przez łączenie - 8

Page 71: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

71

Sortowanie przez łączenie - 9

Page 72: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

72

Sortowanie przez łączenie - 10

Page 73: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

73

Sortowanie przez łączenie - 11

Page 74: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

74

Sortowanie przez łączenie - 12

Page 75: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

75

Sortowanie przez łączenie - 13

Page 76: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

76

Sortowanie przez łączenie - 14

Page 77: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

77

Sortowanie przez łączenie - 15

Page 78: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

78

Sortowanie przez łączenie - 16

Page 79: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

79

Sortowanie przez łączenie - 17

Page 80: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

80

Sortowanie przez łączenie - 18

Page 81: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

81

Sortowanie przez łączenie - 19

Page 82: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

82

Sortowanie przez łączenie - 20

Page 83: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

83

Sortowanie przez łączenie - 21

Page 84: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

84

Sortowanie przez łączenie - 22

Page 85: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

85

Sortowanie przez łączenie – podsumowanie

Sortowanie n liczb

– jeśli n=1 – trywialne

– rekursywnie sortujemy 2 ciągi n/2 i

n/2 liczb

– łączymy dwa ciągi w czasie Θ(n)

Strategia

– Podział problemu na mniejsze, ale

analogiczne podproblemy

– Rekursywne rozwiązywanie

podproblemów

– Łączenie otrzymanych rozwiązań

Page 86: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

86

Sortowanie przez łączenie – czas działania

Czas działania algorytmu może być

reprezentowany przez następującą

zależność rekurencyjną:

Po rozwiązaniu dostajemy:

(1) if 1( )

2 ( / 2) ( ) if 1

nT n

T n n n

Θ ==

+ Θ >

)lg()( nnnT Θ=

Page 87: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

87

Wieże Hanoi

Mamy 3 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 mam przenieść tylko jeden dysk

Page 88: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

88

Wieże Hanoi

Page 89: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

89

Rozwiązanie rekursywne

Page 90: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

90

Algorytm rekursywny

INPUT: n – 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);

INPUT: n – 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);

Poprawność algorytmu łatwo pokazać przez indukcję względem n.

Page 91: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

91

Ilość kroków

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

154

315

73

32

11

M(n)n

Page 92: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

92

Ilość kroków

Rozwijając tę zależność dostajemy

M(n) = 2M(n-1) + 1

= 2*[2*M(n-2)+1] + 1 = 22 * M(n-2) + 1+2

= 22 * [2*M(n-3)+1] + 1 + 2

= 23 * M(n-3) + 1+2 + 22 =…

Po k krokach

M(n) = 2k * M(n-k) + 1+2 + 22 + … + 2n-k-1

Dla k = n-1

M(n) = 2n-1 * M(1) + 1+2 + 22 + … + 2n-2

= 1 + 2 + … + 2n-1 = 2n-1

Page 93: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

93

Sortowanie

Page 94: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

94

Sortowanie - zadanie

Definicja (dla liczb):

wejście: ciąg n liczb A = (a1, a2, …, an)

wyjście: permutacja (a1,…, a’n) taka, że a’1 ≤ … ≤ a’n

Po co sortować?

– Podstawowy problem dla algorytmiki

– Wiele algorytmów wykorzystuje sortowanie jako procedurę pomocniczą

– Pozwala pokazać wiele technik

– Dobrze zbadane (czas)

Page 95: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

95

Sortowanie – taksonomia

Wewnętrzne i zewnętrzne

– Zależnie od miejsca przechowywania zbioru: (RAM czy dysk)

Sortowanie tablic i sortowanie list łączonych

– zależnie od struktury danych (pliku);

– różny sposób dostępu (bezpośredni dla tablicy, sekwencyjny dla listy).

„W miejscu” lub nie

– Nie wymaga dodatkowej pamięci

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.

Bezpośrednie i pośrednie

– zależnie od tego przemieszczamy całe obiekty, czy tylko wskaźniki

(indeksy) do nich

Page 96: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

96

Zestawienie czasów działania

Przez wybór: O(N2) zawsze

Bąbelkowe: O(N2) najgorszy przypadek; O(N) najlepszy przyp.

Wstawianie: O(N2) średnio; O(N) najlepszy przypadek

Shellsort: O(N4/3)

Heapsort: O(NlogN) zawsze

Mergesort: O(NlogN) zawsze

Quicksort: O(NlogN) średnio; O(N2) najgorszy przypadek

Zliczanie: O(N) zawsze

Radix sort: O(N) zawsze

zewnętrzne: O(b logb)) dla pliku o b „stronach”.

Page 97: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

97

Sortowanie przez wybór – pomysł

Znajdujemy najmniejszy element ciągu i zamieniamy go z

pierwszym elementem. Powtarzamy to dla podciągu bez

pierwszego elementu, itd.

Znajdź minimum i zamieńz pierwszym elementem

X

X

Page 98: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

98

Sortowanie przez wybór – pseudokod

Selection_Sort(int A)

1 for i ← 1 to length[A]

2 do min ← i;

3 for j ← i+1 to length[A]

4 do if A[j] < A[min] then min ← j;

5 Exchange A[min] ↔ A[i]

Page 99: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

99

ciąg: EASYQUESTION - rozmiar 12 znaków

#porównań #zamian

EASYQUESTION

AESYQUESTION 11 1

AESYQUESTION 10 1

AEEYQUSSTION 9 1

AEEIQUSSTYON 8 1

AEEINUSSTYOQ 7 1

AEEINOSSTYUQ 6 1

AEEINOQSTYUS 5 1

AEEINOQSTYUS 4 1

AEEINOQSSYUT 3 1

AEEINOQSSTUY 2 1

AEEINOQSSTUY 1 1

Razem 66 11

1

2

3

4

5

6

7

8

9

10

11

Sortowanie przez wybór – przykład

iteracja

Page 100: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

100

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ść zamian: nie

O(N2) zawsze (bez znaczenia jaki jest układ elementów w danych –

ważna tylko ilość)

Page 101: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

101

Sortowanie bąbelkowe (przez zamianę)

Przechodzimy przez ciąg od jego końca, porównując sąsiadujące

elementy i ewentualnie zamieniając je miejscami. Powtarzamy te

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.

Porównanie do wypływających

bąbelków – stąd nazwa.

Page 102: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

102

Sortowanie bąbelkowe – pseudokod

BUBBLE_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 then exchange A[j] ↔ A[j - 1]

Page 103: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

103

Ciąg: EASYQUESTION, (12 znaków)

porównań zamian

EASYQUESTION (najgorszy przyp)

AEESYQUISTNO 11 (11) 8 (11)

AEEISYQUNSTO 10 (10) 6 (10)

AEEINSYQUOST 9 (9) 6 (9)

AEEINOSYQUST 8 (8) 4 (8)

AEEINOQSYSUT 7 (7) 3 (7)

AEEINOQSSYTU 6 (6) 2 (6)

AEEINOQSSTYU 5 (5) 1 (5)

AEEINOQSSTUY 4 (4) 1 (4)

AEEINOQSSTUY 3 (3) 0 (3)

(2) (2)

(1) (1)

razem 63 (66) 31 (66)

iteracja

1

2

3

4

5

6

7

8

9

Sortowanie bąbelkowe – przykład

Page 104: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

104

Sortowanie bąbelkowe – czas wykonania

Zależność od danych wejściowych:– Ilość potrzebnych przejść: tak

– Ilość porównań w jednym przejściu: nie

– Ilość zamian: tak

Najgorszy przypadek: O(N2)– Dane odwrotnie posortowane, np.: JIHGFEDCBA.

– N-1 przejść– (N-1)N/2 porównań i (N-1)N/2 zamian

Najlepszy przypadek: O(N)– Jeśli elementy są już posortowane, np.: ABCDEFGHIJ.

– Tylko jedno przejście. Stąd mamy N-1 porównań i 0 zamian.

Page 105: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

105

Sortowanie przez wstawianie – pomysł

Dla każdego elementu ciągu (od lewej do prawej), wstawiamy go

we właściwe miejsce ciągu elementów poprzedzających go (już

posortowanych).

Page 106: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

106

Sortowanie przez wstawianie – pseudokod

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[i]>key

5 do A[i+1] ← A[i]

6 i ← i-1

7 A[i+1] ← key

Page 107: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

107

Ciąg: EASYQUESTION, (12 znaków)

porównań zamian

(najgorszy przyp.)

EASYQUESTION

AESYQUESTION 1 (1) 1 (1)

AESYQUESTION 1 (2) 0 (2)

AESYQUESTION 1 (3) 0 (3)

AEQSYUESTION 3 (4) 2 (4)

AEQSUYESTION 2 (5) 1 (5)

AEEQSUYSTION 5 (6) 4 (6)

AEEQSSUYTION 3 (7) 2 (7)

AEEQSSTUYION 3 (8) 2 (8)

AEEIQSSTUYON 7 (9) 6 (9)

AEEIOQSSTUYN 7 (10) 6 (10)

AEEINOQSSTUY 8 (11) 7 (11)

razem 41 (66) 31 (66)

iteracja

1

2

3

4

5

6

7

8

9

10

11

Sortowanie przez wstawianie – przykład

Page 108: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

108

Sortowanie przez 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(N2)

– Elementy odwrotnie posortowane np.: JIHGFEDCBA.

– (N-1)N/2 porównań i (N-1)N/2 zamian.

Najlepszy przypadek: O(N)

– Elementy już posortowane np.: ABCDEFGHIJ.

– Jedno porównanie i 0 zamian w każdej iteracji. Razem, N-1

porównań i brak zamian.

Page 109: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

109

Shellsort – pomysł

Modyfikacja (rozszerzona wersja) sortowania przez wstawianie

Dążymy do zmniejszenia ilości zamian – albo ciągi krótkie, albo

lepsze („bliższe” posortowania).

Shellsort wykonuje sortowanie podciągów:

– Wybieramy ciąg liczb (zwany ciągiem przyrostów) ht, … , h2, h1 ;

– h1=1; ht > … > h2 >h1 ;

– Sortujemy ciągi elementów odległych o ht, ht-1, ht-2,…,h1.

Page 110: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

110

Shellsort – kod w C

void shellsort (int[ ] a, int n) int i, j, k, h, v; int[ ] cols = 1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861,

336, 112, 48, 21, 7, 3, 1 for (k=0; k<16; k++)

h=cols[k]; for (i=h; i<n; i++)

v=a[i]; j=i; while (j>=h && a[j-h]>v)

a[j]=a[j-h]; j=j-h;

a[j]=v;

Page 111: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

111

Shellsort – przykład

ciąg: EASYQUESTION (12 znaków)

ciąg przyrostów 4, 1.

porównań zamian

EASYQUESTION

EASYQUESTION 2 0

EASYQIESTUON 3 1

EAEYQIOSTUSN 3 2

EAENQIOSTUSY 3 3

Razem w tej fazie 11 6

faza 1: przyrost = 4

Page 112: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

112

Shellsort – przykład

porównań zamian

EAENQIOSTUSY

AEENQIOSTUSY 1 1

AEENQIOSTUSY 1 0

AEENQIOSTUSY 1 0

AEENQIOSTUSY 1 0

AEEINQOSTUSY 3 2

AEEINOQSTUSY 2 1

AEEINOQSTUSY 1 0

AEEINOQSTUSY 1 0

AEEINOQSTUSY 1 0

AEEINOQSSTUY 3 2

AEEINOQSSTUY 1 0

Razem w tej fazie 16 6

faza 2: przyrost= 1

Page 113: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

113

Shellsort – przykład

Razem 27 porównań i 12 zamian.

Dla sortowania przez wstawiania odpowiednio 41 i 31 !!!

– Polepszenie dostajemy przez wstępne posortowanie, krótkich

podciągów

Zwykle stosuje się ciągi przyrostów o więcej niż 2 elementach.

Page 114: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

114

Shellsort – czas działania

Nie ma możliwości przeprowadzenie dokładnej analizy dla przypadki

ogólnego (wyniki są oparte o badania empiryczne).

Wybór ciągu przyrostów ma zasadniczy wpływ na czas sortowania.

– Dla ciągu podanego przez Shell’a: O(N2)

• Imax = Floor(N/2), Ik = Floor(Ik+1/2).

• np N=64:1, 2, 4, 8, 16, 32

– Dla ciągu podanego przez Knuth’a: O(N3/2)

• I1=1, Ik+1 = 1+3*Ik.

• 1, 4, 13, 40, 121, 364, …

Page 115: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

115

Mergesort – pomysł

Dzielimy ciąg na podciągi, sortujemy te podciągi, a następnie

łączymy zachowując porządek.

– Przykład algorytmu typu „dziel i zwyciężaj”.

– Potrzeba dodatkowego miejsca dla tych podciągów – nie jest to

sortowanie „w miejscu”.

• Można realizować ten proces „w miejscu”, ale rośnie stopień

komplikacji.

Page 116: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

116

Mergesort – przykład

ciąg: EASYQUESTION (12 znaków)

EASYQUESTION

EASYQU ESTION

EAS YQU EST ION

E AS Y QU E ST I ON

A S Q U S T O N

podział

Page 117: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

117

Mergesort – przykład

AEEINOQSSTUY

AEQSUY EINOST

AES QUY EST INO

E AS Y QU E ST I NO

A S Q U S T O N

łaczenie

A E S

Q U Y

C1

C2

C3

Page 118: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

118

Mergesort - pseudokod

MERGE-SORT(A, p, r)

1 if p < r

2 then q ← (p + r)/2

3 MERGE-SORT(A, p, q)

4 MERGE-SORT(A, q + 1, r)

5 MERGE(A, p, q, r)

Page 119: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

119

Mergesort - pseudokod

MERGE(A, p, q, r)

1 n1 ← q - p + 1

2 n2 ← r - 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] ← ∞9 R[n2 + 1] ← ∞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 + 1

16 else A[k] ← R[j]

17 j ← j + 1

Page 120: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

120

Sortowanie w czasie liniowym

Page 121: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

121

Przegląd

Czy możliwe jest sortowanie w czasie lepszym niż dla metod

porównujących elementy (poprzednio – najlepsze algorytmy dawały

czas O(NlogN))?

Algorytmy o liniowym czasie działania:

– Przez zliczanie (Counting-Sort)

– Radix-Sort

– Kubełkowe (Bucket-sort)

Potrzeba dodatkowych założeń!

Page 122: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

122

Sortowanie o czasie liniowym

Możliwe przy dodatkowych informacjach (założeniach) o 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

– Radix-Sort

– Bucket-Sort

Page 123: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

123

Zliczanie (Counting sort)

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 pozycje (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

Page 124: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

124

Zliczanie (Counting sort)

1 32 4 5

Jeśli nie ma powtórzeń i n = k,

Rank[A[i]] = A[i] i B[Rank[A[i]] A[i]

Dla każdego A[i], liczymy elementy

≤ od niego. Daje to rank (pozycję)

elementu

4 12 5A =

B =

Rank =

4

3

521 3

Page 125: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

125

Zliczanie (Counting sort)

5 12 3A =

32 4Rank =

Jeśli nie ma powtórzeń i n < k,

Niektóre komórki tablicy rank

pozostają niewykorzystane, ale

algorytm działa.

B = 52

1

1 3

Page 126: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

126

Zliczanie (Counting sort)

4 12 2A =

1 43 5Rank =

Jeśli n > k i mamy powtórzenia,

umieszczamy na wyjściu

powtarzające się elementy w

takiej kolejności, w jakiej

występowały w oryginalnym

ciągu (stabilność)

B =

3

3 421 2

2

Page 127: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

127

Zliczanie (Counting sort)

Counting-Sort(A, B, k)

1. for i 0 to k

2. do C[i] 0

3. for j 1 to length[A]

4. do C[A[j]] C[A[j]] +1

5. /* C zawiera ilości elementów równych i

6. for i 1 to k

7. do C[i] C[i] + C[i –1]

8. /* C zawiera ilości elementów ≤ i

9. for j length[A] downto 1

10. do B[C[A[j]]] A[j]

11. C[A[j]] C[A[j]] – 1

A[1..n] – tablica wejściowa

B [1..n] – tablica wyjściowa

C [0..k] – pomocnicza tablica (do zliczania)

Page 128: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

128

Sortowanie przez zliczanie – przykład (1)

n = 8k = 6

B[C[A[j]]] A[j]

C[A[j]] C[A[j]] – 1

po p. 11

C[A[j]] C[A[j]] +1po p.4C =

0 1 2 3 4 5

2 20 3 0 1

2 35 0 2 3 0 3A =

1 2 3 4 5 6 7 8

2 42 7 7 8C =

0 1 2 3 4 5

C[i] C[i] + C[i –1]po p. 7

2 42 7 8C =

0 1 2 3 4 5

7

1 2 3 4 5 6 7 8

B = 3

6

Page 129: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

129

Sortowanie przez zliczanie – przykład (2)

0 3B =

2 42 6 7 8C =

0 1 2 3 4 5

1 2 3 4 5 6 7 8

2 35 0 2 3 0 3A =

1 2 3 4 5 6 7 8

2 42 6 7 8C =

0 1 2 3 4 5

1

Page 130: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

130

Sortowanie przez zliczanie – przykład (3)

0 3B =

1 42 6 7 8C =

0 1 2 3 4 5

1 2 3 4 5 6 7 8

2 35 0 2 3 0 3A =

1 2 3 4 5 6 7 8

2 42 6 7 8C =

0 1 2 3 4 5

3

5

Page 131: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

131

Counting sort – czas działania

Pętla for w p.1-2 zajmuje czas Θ(k)

Pętla for w p.3-4 zajmuje czas Θ(n)

Pętla for w p.6-7 zajmuje czas Θ(k)

Pętla for w p.9-11 zajmuje czas Θ(n)

Stąd dostajemy łączny czas Θ(n+k)

Ponieważ k = O(n), T(n) = Θ(n) algorytm jest optymalny!!

Konieczne jest założenie k = O(n). Jeśli k >> n to potrzeba to

potrzeba dużej ilości pamięci.

Nie jest to sortowanie „w miejscu”.

Page 132: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

132

Radix sort – sortowanie pozycyjne

wejście: n liczb całkowitych, d-cyfrowych, łańcuchów o d-pozycjach

pomysł: zajmować się tylko jedną z cyfr (sortować względem kolejnych

pozycji – cyfr/znaków). Zaczynamy od najmniej znaczącej

cyfry/znaku, potem kolejne pozycje (cyfry/znaki), aż do najbardziej

znaczącej. Musimy stosować metodą stabilną. Ponieważ zbiór

możliwych wartości jest mały (cyfry – 0-9, znaki ‘a’-’z’) możemy

zastosować metodę zliczania, o czasie O(n)

Po zakończeniu ciąg będzie posortowany!!

Page 133: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

133

Radix sort – przykład

6 5 7

4 5 7

3 5 5

8 3 9

4 3 6

3 2 9

7 2 0

3 5 5

7 2 0

4 3 6

8 3 9

6 5 7

4 5 7

3 2 9

8 3 9

3 2 9

6 5 7

4 5 7

4 3 6

3 5 5

7 2 0

8 3 9

7 2 0

6 5 7

4 5 7

4 3 6

3 5 5

3 2 9

Page 134: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

134

Radix-Sort – pseudokod

Radix-Sort(A, d)

1. for i 1 to d

2. do zastosuj stabilną metodę sortowania do cyfry d dla tablicy A

uwagi:

• złożoność: T(n) = Θ(d(n+k)) Θ(n) dla stałego d i k = O(1)

• wartości cyfr/znaków są z zakresu [0..k –1] dla k = O(1)

• Metoda stosowana dla poszczególnych pozycji musi być stabilna!

Page 135: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

135

Sortowanie kubełkowe – Bucket sort

wejście: n liczb rzeczywistych z przedziału [0..1) ważne jest, aby były

równomiernie rozłożone (każda wartość równie prawdopodobna)

pomysł: dzielimy przedział [0..1) na n podprzedziałów („kubełków”):0, 1/n,

2/n. … (n–1)/n. Elementy do odpowiednich kubełków, ai: 1/i ≤ ai ≤ 1/(i+1).

Ponieważ rozkład jest równomierny to w żadnym z przedziałów nie

powinno znaleźć się zbyt wiele wartości. Jeśli wkładamy je do kubełków

zachowując porządek (np. przez wstawianie – Insertion-Sort),

dostaniemy posortowany ciąg.

Page 136: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

136

Bucket sort – przykład

. 21

.12

.23

.68

.94

.72

.26

.39

.17

.78

7

6

8

9

5

4

3

2

1

0

.17.12

.26.23.21

.39

.68

.78.72

.94

.68

.72

.78

.94

.39

.26

.23

.21

.17

.12

Page 137: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

137

Bucket-Sort

Bucket-Sort(A)

1. n length(A)

2. for i 0 to n

3. do wstaw A[i] do listy B[floor(nA[i])]

4. for i 0 to n –1

5. do Insertion-Sort(B[i])

6. Połącz listy B[0], B[1], … B[n –1]

A[i] tablica wejściowa

B[0], B[1], … B[n –1] lista „kubełków”

Page 138: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

138

Bucket-Sort – złożoność czasowa

Wszystkie instrukcje z wyjątkiem 5 (Insertion-Sort) wymagają czasu O(n),

w przypadku pesymistycznym.

W przypadku pesymistycznym, O(n) liczb trafi do jednego „kubełka” czyli

ich sortowanie zajmie czas O(n2).

Jednak w średnim przypadku stała ilość elementów wpada do jednego

przedziału – stąd czas średni wyniesie O(n).

Page 139: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

139

Sortowanie

Quicksort i Heapsort

Page 140: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

140

Sortowanie - zadanie

Definicja (dla liczb):

wejście: ciąg n liczb A = (a1, a2, …, an)

wyjście: permutacja (a1,…, a’n) taka, że a’1 ≤ … ≤ a’n

Page 141: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

141

Zestawienie czasów działania

Przez wybór: O(N2) zawsze

Bąbelkowe: O(N2) najgorszy przypadek; O(N) najlepszy przyp.

Wstawianie: O(N2) średnio; O(N) najlepszy przypadek

Shellsort: O(N4/3)

Heapsort: O(NlogN) zawsze

Mergesort: O(NlogN) zawsze

Quicksort: O(NlogN) średnio; O(N2) najgorszy przypadek

Zliczanie: O(N) zawsze

Radix sort: O(N) zawsze

zewnętrzne: O(b logb)) dla pliku o b „stronach”.

Page 142: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

142

Dzisiaj:

Dwa algorytmy sortowania:

Quicksort

– Bardzo popularny algorytm, bardzo szybki w średnim przypadku

Heapsort

– Wykorzystuje strukturę kopca (heap)

Page 143: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

143

Sortowanie szybkie (Quick Sort) - pomysł

Jest to najszybszy w praktyce algorytm sortowania, pozwala na

efektywne implementacje.

– średnio: O(NlogN)

– najgorzej O(N2), przypadek bardzo mało prawdopodobny.

Procedura:

– Wybieramy element osiowy (pivot ).

– Dzielimy ciąg na dwa podciągi: elementów mniejszych lub równych

od osiowego oraz elementów większych od osiowego. Powtarzamy

takie postępowanie, aż osiągniemy ciąg o długości 1.

– Algorytm typu – „dziel i zwyciężaj”.

– Jest to metoda sortowania w miejscu (podobnie jak Insert-sort,

przeciwnie do np. Merge-sort), czyli nie wymaga dodatkowej

pamięci

Page 144: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

144

Quicksort – algorytm

QUICKSORT(A, p, r)

1 if p < r

2 then q ← PARTITION(A, p, r)

3 QUICKSORT(A, p, q - 1)

4 QUICKSORT(A, q + 1, r)

Problemy:

1. Wybór elementu osiowego;

2. Podział (partition).

Page 145: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

145

Quicksort – podział

Funkcja partition dzieli ciąg na dwa podciągi: elementów mniejszych (bądź równych) od osiowego i większych od niego

a[j] | a[j] <= a[i]

dla j ∈[left, i-1]

a[k] | a[k] > a[i]

dla k ∈[i+1,right]

a[i]

wynik

quicksort(a, left, i-1)

wynik

quicksort(a, i+1, right)

Po podziale:El. osiowy

Page 146: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

146

Quicksort – przykład podziału

ciąg: EASYQUESTION (12 znaków). El. osiowy: N

E A S Y Q U E S T I O N

Przeglądaj aż: a[i] > a[right] Przeglądaj aż: a[j] <= a[right]

i jSwap(a[i], a[j])

E A I Y Q U E S T S O Ni j

Swap(a[i], a[j])

E A I E Q U Y S T S O Ni

j Swap(a[i], a[right])

(indeksy i oraz j „minęły” się)

E A I E N U Y S T S O Q

Lewy podciąg Prawy podciąg

Page 147: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

147

Quicksort – wybór elementu osiowego

opcja 1: zawsze wybierać skrajny element (pierwszy lub ostatni).

– 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);

– Wady: czasochłonne i nie gwarantuje sukcesu.

opcja 3: wybieramy medianę z pierwszych/ostatnich/środkowych 3/5/7

elementów.

– gwarantuje, że nie będzie zdegenerowanych podciągów (pustych).

– kompromis pomiędzy opcją 1 i 2

Page 148: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

148

Podział – pseudokod (opcja 1)

Partition(A, Left, Right)

1. Pivot A[Right]

2. i Left – 1

3. for j Left to Right–1

4. do if (A[j] ≤ Pivot)

5. then i i + 1

6. Exchange(A[i], A[j])

7. Exchange (A[i+1], A[Right])

8. return i +1

Page 149: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

149

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ównie prawdopodobne(1:n-1, 2:n-2, ..., n-1:1), z prawdopodobieństwem 1/n

Randomizacja jest drogą do unikania najgorszego przypadku

Page 150: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

150

Randomizowany Quicksort

Randomized-Partition(A,p,r)

01 i←Random(p,r)

02 exchange A[r] ↔A[i]

03 return Partition(A,p,r)

Randomized-Quicksort(A,p,r)01 if p<r then

02 q←Randomized-Partition(A,p,r)

03 Randomized-Quicksort(A,p,q)

04 Randomized-Quicksort(A,q+1,r)

Page 151: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

151

Quicksort – czas działania

Najgorszy przypadek: O(N2)

– Podciągi zawsze mają długości 0 i N-1 (el. Osiowy jest zawsze

najmniejszy/największy). Np. dla posortowanego ciągu i pierwszej

opcji wyboru el. osiowego.

Najlepszy przypadek: O(NlogN)

– Podział jest zawsze najlepszy (N/2). El. osiowy zawsze jest

medianą.

Średnio: O(NlogN)

Page 152: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

152

Quicksort – najlepszy przypadek

Podciągi otrzymane w wyniku podziału są równe

( ) 2 ( / 2) ( )T n T n n= + Θ

Page 153: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

153

Quicksort – najgorszy przypadek

Page 154: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

154

Quicksort- czas działania

T(N) = T(i) + T(N-i-1) + N for N > 1

T(0) = T(1) = 1

– T(i) i T(N-i-1) dla podziału i/N-i-1.

– N dla podziału 1/N-1(liniowe – przeglądamy wszystkie elementy).

Page 155: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

155

Quicksort – czas działania

najgorzej: T(N) = T(0) + T(N-1) + N = T(N-1) + N = O(N2)

najlepiej: T(N) = 2T(N/2) + N = O(NlogN)

„średnio”:

T(N) = (1/N) ∑∑∑∑i=0N-1T(i) + (1/N) ∑∑∑∑i=0

N-1T(N-i-1) + N

= (2/N) ∑∑∑∑j=0N-1T(j) + N = O(NlogN)

Page 156: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

156

Quicksort - uwagi

Małe ciągi

– Quicksort zachowuje się źle 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)

Porównanie z mergesort:

– Oba zbudowane na zasadzie „dziel i zwyciężaj”.

– Mergesort wykonuje sortowanie w fazie łączenia.

– Quicksort wykonuje prace w fazie podziału.

Page 157: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

157

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

– Wartość klucza w węźle jest większa lub równa od wartości kluczy

wszystkich dzieci; własność taka jest zachowana dla lewego i prawego

poddrzewa (zawsze)

Page 158: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

158

Heap Sort – reprezentacja tablicowa kopca

1423978101516

10987654321

Parent (i)return i/2

Left (i)return 2i

Right (i)return 2i+1

Własność kopca:

A[Parent(i)] ≥ A[i]

poziomy: 3 2 1 0

Page 159: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

159

Heap Sort – reprezentacja kopca w tablicy

Zauważmy połączenia w drzewie – dzieci węzła i występują na pozycjach

2i oraz 2i+1

Czemu to jest wygodne?

– Dla reprezentacji binarnej, dzieleniu/mnożeniu przez 2 odpowiada

przesuwanie (szybka operacja)

– Dodawanie jedynki oznacza zmianę najmłodszego bitu (po przesunięciu)

Page 160: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

160

Kopcowanie (Heapify)

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 złamanie

własności kopca

Metoda Kopcowania (Heapify) 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

Page 161: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

161

Kopcowanie (Heapify)

Page 162: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

162

Kopcowanie (Heapify) – przykład

Page 163: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

163

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: Θ(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.

– Inaczej mówiąc

• Czas działania dla drzewa o wysokości h: O(h)

( ) (2 /3) (1) ( ) (log )T n T n T n O n≤ + Θ ⇒ =

Page 164: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

164

Budowa kopca

Konwertujemy tablicę A[1...n], gdzie n = length[A], na kopiec

Zauważmy, że elementy w A[(n/2 + 1)...n] są już zbiorem kopców -jednoelementowych!

Page 165: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

165

Budowanie kopca – 1

Page 166: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

166

Budowanie kopca – 2

Page 167: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

167

Budowanie kopca – 3

Page 168: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

168

Budowa kopca – analiza

Poprawność: indukcja po i, (wszystkie drzewa o korzeniach m > i są

kopcami)

Czas działania: n wywołań kopcowania (Heapify) = n O(lg n) = O(n lg n)

Wystarczająco dobre ograniczenie – O(n lg n) dla zadania sortowanie

(Heapsort), ale czasem kopiec budujemy dla innych celów

Page 169: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

169

Sortowanie za pomocą kopca – Heap Sort

Czas działania O(n lg n) + czas budowy kopca (O(n))

O( )n

Page 170: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

170

Heap Sort – 1

Page 171: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

171

Heap Sort – 2

Page 172: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

172

Heap Sort – podsumowanie

Heap sort wykorzystuje strukturę kopca przez co dostajemy

asymptotycznie optymalny czas sortowania

Czas działania O(n log n) – podobnie do merge sort, i lepiej niż wybór,

wstawianie czy bąbelkowe

Sortowanie w miejscu – podobnie do sortowania przez wybór, wstawianie

czy bąbelkowego

Page 173: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

173

Dynamiczne struktury danych

Page 174: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

174

Wprowadzenie

Popularne dynamiczne struktury danych (ADT)

stosy, kolejki, listy – opis abstrakcyjny

Listy liniowe

Implementacja tablicowa stosu i kolejki

Drzewa

Możliwe implementacje

Plan wykładu

Page 175: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

175

Wprowadzenie

Do tej pory najczęściej zajmowaliśmy się jedną strukturą danych –

tablicą. Struktura taka ma charakter statyczny – jej rozmiar jest

niezmienny. Powoduje to konieczność poznania wymaganego rozmiaru

przed rozpoczęciem działań (ewentualnie straty miejsca – deklarujemy

„wystarczająco” dużą tablicę).

W wielu zadaniach wygodniejsza jest struktura o zmiennym rozmiarze

(w zależności od aktualnych potrzeb) – struktura dynamiczna.

Potrzebujemy struktury pozwalającej na przechowywanie elementów

niezależnie od ich fizycznego położenia.

logicznie fizycznie

2 50 3 4 1 3 42 1 0 5

Page 176: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

176

Wprowadzenie

Przykładowe operacje dla struktur danych:

– Insert(S, k): wstawianie nowego elementu

– Delete(S, k): usuwanie elementu

– Min(S), Max(S): odnajdowanie najmniejszego/największego elementu

– Successor(S,x), Predecessor(S,x): odnajdowanie

następnego/poprzedniego elementu

Zwykle przynajmniej jedna z tych operacji jest kosztowna czasowo

(zajmuje czas O(n)). Czy można lepiej?

Page 177: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

177

Abstrakcyjne typy danych (Abstract Data Types –ADT )

Abstrakcyjnym typem danych nazywany formalną specyfikację sposobu

przechowywania obiektów oraz zbiór dobrze opisanych operacji na tych

obiektach.

Jaka jest różnica pomiędzy strukturą danych a ADT?

struktura danych (klasa) jest implementacją ADT dla specyficznego

komputera i systemu operacyjnego.

Page 178: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

178

Popularne dynamiczne ADT

Listy łączone

Stosy, kolejki

Drzewa – z korzeniem (rooted trees), binarne, BST, czerwono-czarne, AVL itd.

Kopce i kolejki priorytetowe (późniejsze wykłady)

Tablice z haszowaniem (późniejsze wykłady)

Page 179: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

179

Listy

Lista L jest liniową sekwencją elementów.

Pierwszy element listy jest nazywany head, ostatni tail. Jeśli obydwa

są równe null, to lista jest pusta

Każdy element ma poprzednik i następnik (za wyjątkiem head i tail)

Operacje na liście:

– Successor(L,x), Predecessor(L,x)

– List-Insert(L,x)

– List-Delete(L,x)

– List-Search(L,k)

2 20 3 0 1

xhead tail

Page 180: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

180

Listy łączone

Rozmieszczenie fizyczne obiektów w pamięci nie musi odpowiadać

ich logicznej kolejności; wykorzystujemy wskaźniki do obiektów (do

następnego/poprzedniego obiektu)

Manipulując wskaźnikami możemy dodawać, usuwać elementy do

listy bez przemieszczania pozostałych elementów listy

Lista taka może być pojedynczo lub podwójnie łączona.

a1 a2 ana3

head

null

null

tail

Page 181: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

181

Węzły i wskaźniki

Węzłem nazywać będziemy obiekt

przechowujący daną oraz wskaźnik do

następnej danej i (opcjonalnie – dla listy

podwójnie łączonej) wskaźnik do

poprzedniej danej. Jeśli nie istnieje

następny obiekt to wartość wskaźnika

będzie “null”

Wskaźnik oznacza adres obiektu w

pamięci

Węzły zajmują zwykle przestrzeń: Θ(1)

struct node

key_type key;

data_type data;

struct node *next;

struct node *prev;

data

next

prev

key

Page 182: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

182

Wstawianie do listy (przykład operacji na liście)

wstawianie nowego węzła q pomiędzy węzły p i r:

a1 a3

p r

a2

p r

a1 a2

q

a3

next[q] r

next[p] q

Page 183: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

183

Usuwanie z listy

usuwanie węzła q

a1 a2

p q

a3

r

a1 a3

p r

next[p] r

next[q] null

a2

q

null

Page 184: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

184

Operacje na liście łączonej

List-Search(L, k)

1. x head[L]

2. while x ≠ null and key[x] ≠ k

3. do x next[x]

4. return x

List-Insert(L, x)

1. next[x] head[L]

2. if head[L] ≠ null

3. then prev[head[L]] x

4. head[L] x

5. prev[x] null

List-Delete(L, x)

1. if prev[L] ≠ null

2. then next[prev[x]] next[x]

3. else head[L] next[x]

4. if next[L] ≠ null

5. then prev[next[x]] prev[x]

Page 185: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

185

Listy podwójnie łączone

a1 a2 a4a3

head

nullnull

tailx

Listy cykliczne: łączymy element pierwszy z ostatnim

Page 186: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

186

Stosem S nazywany liniową sekwencję elementów do której nowy

element x może zostać wstawiony jedynie na początek, analogicznie

element może zostać usunięty jedynie z początku tej sekwencji.

Stos rządzi się zasadą Last-In-First-Out (LIFO).

Operacje dla stosu:

– Stack-Empty(S)

– Pop(S)

– Push(S,x)

Stosy

PopPush

null

head2015

Page 187: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

187

Kolejki

Kolejka Q jest to liniowa sekwencja elementów do której nowe

elementy wstawiane są na końcu sekwencji, natomiast elementy

usuwane są z jej początku.

Zasada First-In-First-Out (FIFO).

Operacje dla kolejki:

– Queue-Empty(Q)

– EnQueue(Q, x)

– DeQueue(Q)

2 20 3 0 1

head tail

DeQueue EnQueue

Page 188: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

188

Implementacja stosu i kolejki

Tablicowa

– Wykorzystujemy tablicę A o n elementach A[i], gdzie n jest maksymalną

ilością elementów stosu/kolejki.

– Top(A), Head(A) i Tail(A) są indeksami tablicy

– Operacje na stosie/w kolejce odnoszą się do indeksów tablicy i elementów

tablicy

– Implementacja tablicowa nie jest efektywna

Listy łączone

– Nowe węzły tworzone są w miarę potrzeby

– Nie musimy znać maksymalnej ilości elementów z góry

– Operacje są manipulacjami na wskaźnikach

Page 189: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

189

Implementacja tablicowa stosu

Push(S, x)

1. if top[S] = length[S]

2. then error “overflow”

3. top[S] top[S] + 1

4. S[top[S]] x

Pop(S)

1. if top[S] = -1

2. then error “underflow”

3. else top[S] top[S] – 1

4. return S[top[S] +1]

1 5 2 3

Kierunek wstawiania

top

Stack-Empty(S)

1. if top[S] = -1

2. then return true

3. else return false

0 1 2 3 4 5 6

Page 190: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

190

Implementacja tablicowa kolejki

Enqueue(Q, x)

1. Q[tail[Q]] x

2. if tail[Q] = length[Q]

3. then tail[Q] x

4. else tail[Q] (tail[Q]+1)mod n

Dequeue(Q)

1. x Q[head[Q]]

2. if head[Q] = length[Q]

3. then head[Q] 1

4. else head[Q] (head[Q]+1)mod n

5. return x

1 5 2 3 0

headtail

Page 191: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

191

Drzewa z korzeniem

Drzewem z korzeniem T nazywamy ADT dla którego elementy są

zorganizowane w strukturę drzewiastą.

Drzewo składa się z węzłów przechowujących obiekt oraz krawędzi

reprezentujących zależności pomiędzy węzłami.

W drzewie występują trzy typy węzłów: korzeń (root), węzły

wewnętrzne, liście

Własności drzew:

– Istnieje droga z korzenia do każdego węzła (połączenia)

– Droga taka jest dokładnie jedna (brak cykli)

– Każdy węzeł z wyjątkiem korzenia posiada rodzica (przodka)

– Liście nie mają potomków

– Węzły wewnętrzne mają jednego lub więcej potomków (= 2 binarne)

Page 192: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

192

Drzewa z korzeniem

A

B

E F

MLK

D

G J

N

C

H I

0

1

2

3

Page 193: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

193

Terminologia

Rodzice (przodkowie) i dzieci (potomkowie)

Rodzeństwo (sibling) – potomkowie tego samego węzła

Relacja jest dzieckiem/rodzicem.

Poziom węzła

Ścieżka (path): sekwencja węzłów n1, n2, … ,nk takich, że ni jest

przodkiem ni+1. Długością ścieżki nazywamy liczbę k.

Wysokość drzewa: maksymalna długość ścieżki w drzewie od korzenia

do liścia.

Głębokość węzła: długość ścieżki od korzenia do tego węzła.

Page 194: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

194

Drzewa binarne

A

B C

FED

G

≠A

B C

FED

GPorządek węzłów

jest istotny!!!

Drzewem binarnym T nazywamy drzewo z korzeniem, dla którego

każdy węzeł ma co najwyżej 2 potomków.

Page 195: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

195

Drzewa pełne i drzewa kompletne

Drzewo binarne jest pełne jeśli każdy węzeł wewnętrzny ma dokładnie dwóch potomków.

Drzewo jest kompletne jeśli każdy liść ma tę samą głębokość.

A

B C

ED

GF

A

B C

ED GF

pełne kompletne

Page 196: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

196

Własności drzew binarnych

Ilość węzłów na poziomie d w kompletnym drzewie binarnym wynosi 2d

Ilość węzłów wewnętrznych w takim drzewie:

1+2+4+…+2d–1 = 2d –1 (mniej niż połowa!)

Ilość wszystkich węzłów:

1+2+4+…+2d = 2d+1 –1

Jak wysokie może być drzewo binarne o n liściach: (n –1)/2

Wysokość drzewa:

2d+1 –1= n log (n+1) –1 ≤ log (n)

Page 197: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

197

Tablicowa implementacja drzewa binarnego

A

B C

ED GF

1 2 3 4 5 6 7

20 21 22

A B DC E F G

0

1

22

Poziom

Na każdym poziomie d

mamy 2d elementów

Kompletne drzewo:

parent(i) = floor(i/2)

left-child(i) = 2i

right-child(i) = 2i +1

1

2 3

4 5 6 7

Page 198: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

198

Listowa implementacja drzewa binarnego

A

B C

ED GF

H

Każdy węzeł zawieraDane oraz 3 wskaźniki:• przodek • lewy potomek• prawy potomek

root(T)

data

Page 199: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

199

Listowa implementacja drzewa binarnego (najprostsza)

A

B C

ED GF

H

Każdy węzeł zawieraDane oraz 2 wskaźniki:• lewy potomek• prawy potomek

root(T)

data

Page 200: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

200

Listowa implementacja drzewa (n-drzewa)

A

B D

ED G

Każdy węzeł zawieraDane oraz 3 wskaźniki:• przodek• lewy potomek• prawe rodzeństwo

C

root(T)

F H I

J K

Page 201: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

201

Drzewa poszukiwańbinarnych (BST)

Page 202: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

202

O czym będziemy mówić

Definicja

Operacje na drzewach BST:

– Search

– Minimum, Maximum

– Predecessor, Successor

– Insert, Delete

Struktura losowo budowanych drzew BST

Page 203: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

203

Wprowadzenie

Poszukujemy dynamicznego ADT, który efektywnie będzie obsługiwał

następujące operacje:

– Wyszukiwanie elementu (Search)

– Znajdowanie Minimum/Maximum

– Znajdowanie poprzednika/następnika (Predecessor/Successor)

– Wstawianie/usuwanie elementu (Insert/Delete)

Wykorzystamy drzewo binarne! Wszystkie operacje powinny zajmować

czas Θ(lg n)

Drzewo powinno być zawsze zbalansowane – inaczej czas będzie

proporcjonalny do wysokości drzewa (gorszy od O(lg n))!

Page 204: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

204

Drzewo poszukiwań binarnych (binary search tree)

Struktura drzewa z korzeniem

Każdy węzeł x posiada pola left(x), right(x), parent(x), oraz key(x).

Własność drzewa BST:

Niech x będzie dowolnym węzłem drzewa, natomiast niech y będzie

należał do poddrzewa o korzeniu w x wtedy:.

– Jeżeli należy do lewego poddrzewa to: key(y) ≤ key(x)

– Jeżeli należy do prawego poddrzewa to : key(y) > key(x)

Page 205: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

205

Przykład BST

5

3

5

5

7

8

2

3

72

85

Metody przechodzenia przez drzewo : In-order, pre-order, post-order

Page 206: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

206

Tree-Search(x,k)if x = null or k = key[x]

then return xif k < key[x]

then return Tree-Search(left[x],k)else return Tree-Search(right[x],k)

Tree-Search(x,k)while x ≠ null and k ≠ key[x]

do if k < key[x] then x left[x]else x right[x]

return x

Poszukiwanie w drzewie BST

rekurencyjnie

iteracyjnie

złożoność: O(h)

Page 207: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

207

Przykład

Poszukiwany klucz: 13

Page 208: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

208

Przechodzenie przez wszystkie węzły drzewa

Inorder-Tree-Walk(x)

if x ≠ null

then Inorder-Tree-Walk(left[x])

print key[x]

Inorder-Tree-Walk(right[x])

złożoność: Θ(n)

czas wykonania:

T(0) = Θ(1)

T(n)=T(k) + T(n – k –1) + Θ(1)

Page 209: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

209

Tree-Minimum(x)while left[x] ≠ null

do x left[x]return x

Tree-Maximum(x)while right[x] ≠ null

do x right[x]return x

Odnajdowanie minimum i maksimum

złożoność: O(h)

Page 210: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

210

Przykład – minimum

Page 211: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

211

Odnajdowanie następnika

Następnikiem x nazywamy najmniejszy element y wśród elementów większych od x

Następnik może zostać odnaleziony bez porównywania kluczy. Jest to :

1. null jeśli x jest największym z węzłów.

2. minimum w prawym poddrzewie t jeśli ono istnieje.

3. najmniejszy z przodków x, dla których lewy potomek jest przodkiem x.

Page 212: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

212

Odnajdowanie następnika

x

minimum w prawym poddrzewie t

y

z

xnajmniejszy z przodków x, dla których lewy potomek

jest przodkiem x

Page 213: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

213

Odnajdowanie następnika

Tree-Successor(x)

if right[x] ≠ null // przypadek 2

then return Tree-Minimum(right[x])

y parent[x]

while y ≠ null and x = right[y] // przypadek 3

do x y

y parent[y]

return y

Page 214: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

214

Przykład

Poszukajmy następników dla 15 (przyp. 2), 13 (przyp. 3)

Page 215: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

215

Wstawianie elementów

Wstawianie jest bardzo zbliżone do odnajdowania elementu:

– Odnajdujemy właściwe miejsce w drzewie, w które chcemy wstawić

nowy węzeł z.

Dodawany węzeł z zawsze staje się liściem.

Zakładamy, że początkowo left(z) oraz right(z) mają wartość null.

Page 216: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

216

Wstawanie – przykład

12

5

9

18

1915

17

2

13

Wstawiamy 13 do drzewa

z

Page 217: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

217

Wstawianie – pseudokod

Tree-Insert(T,z)

y null

x root[T]

while x ≠ null

do y x

if key[z] < key[x]

then x left[x]

else x right[x]

parent[z] y

// dla pustego drzewa

if y = null then root[T] z

else if key[z] < key[y]

then left[y] z

else right[y] z

Page 218: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

218

Usuwanie z drzewa BST

Usuwanie elementu jest bardziej skomplikowane niż wstawianie. Można

rozważać trzy przypadki usuwania węzła z:

1. z nie ma potomków

2. z ma jednego potomka

3. z ma 2 potomków

przypadek 1: usuwamy z i zmieniamy u rodzica wskazanie na null.

przypadek 2: usuwamy z a jego dziecko staje się dzieckiem rodzica.

przypadek 3:najbardziej złożony; nie można po prostu usunąć węzła i

przenieść dzieci do rodzica – drzewo przestałoby być binarne!

Page 219: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

219

delete

Usuwanie z drzewa BST - przypadek 1

usuwamy

Page 220: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

220

Usuwanie z drzewa BST przypadek 2

Usuwany węzeł

Page 221: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

221

Usuwanie z drzewa BST

przypadek 3

Rozwiązanie polega na zastąpieniu węzła jego następnikiem.

założenie: jeśli węzeł ma dwóch potomków, jego następnik ma co

najwyżej jednego potomka.

dowód: jeśli węzeł ma 2 potomków to jego następnikiem jest minimum z

prawego poddrzewa. Minimum nie może posiadać lewego potomka

(inaczej nie byłoby to minimum)

Page 222: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

222

Usuwanie z drzewa BST – przypadek 3

z

α β

δ

Usuwamy z

y

w

y

α β

δ

w

Page 223: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

223

Usuwanie z drzewa BST – przypadek 3

usuwamy

następnik

Page 224: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

224

Usuwanie z drzewa BST – pseudokod

Tree-Delete(T,z)

if left[z] = null or right[z] = null /* p. 1 lub 2

then y z

else y Tree-Successor(z)

if left[y] ≠ null

then x left[y]

else x right[y]

if x ≠ null

then parent[x] parent[y]

if parent[y] = null

then root[T] x

else if y = left[parent[y]]

then left[parent[y]] x

else right[parent[y]] xif y ≠ z

then key[z] key[y]return y

Page 225: Syllabus - Kolos Wikikolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 1... · 11 Przykład 1: poszukiwanie liniowe INPUT : A[1..n] – tablica liczb, q – liczba całkowita.

225

Analiza złożoności

Usuwanie: dwa pierwsze przypadki wymagają O(1) operacji: tylko zamiana wskaźników.

Przypadek 3 wymaga wywołania Tree-Successor, i dlatego wymaga czasu O(h).

Stad wszystkie dynamiczne operacje na drzewie BST zajmują czas O(h), gdzie h jest wysokością drzewa.

W najgorszym przypadku wysokość ta wynosi O(n)