ALGORYTMY I STRUKTURY DANYCH WYKŁAD 04 k-ty co do wielkości. Stosy Grażyna Mirkowska PJWSTK, ITN semestr letni 2002
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości2 Plan wykładu 4 Wyszukiwanie 2-go co do wielkości elementu –Algorytm naiwny –Jak poprawić algorytm naiwny –Struktura danych - stos 4 k-ty co do wielkości –Algorytm Hoare –Rekursja czy stos?
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości3 Drugi największy element Problem Dany jest ciąg e elementów e[1],...,e[n] pewnej przestrzeni liniowo uporządkowanej. Znaleźć drugi co do wielkości element tego ciągu. WP = { e[i] e[j] dla i j, n>0}, WK = {1 wynik n, e[j] e[wynik] < e[max] dla j=1,2,...,n } e[wynik] = maximum({e[1]...,e[n]} - maximum{e[1],...,e[n]}) Algorytm naiwny : 1. Znaleźć element maksymalny. 2. Usunąć go z rozważań. 3. Znaleźć element maksymalny w pozostałym zbiorze.
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości4 Algorytm naiwny { i := 2; max :=1; while i n do if e[i] > e[max] then max := i fi; i := i+1; od; pom := e[1]; e[1] := e[max]; e[max] := pom; i:=3; wynik := 2; while i n do if e[i] > e[wynik] then wynik := i fi; i := i+1; od; } Swap(e[1], e[max]); T(n) = 2n -3 Max: = 1; for ( i =2; i e[max]){max:=i;} } wynik := 2; for ( i =3; i e[wynik]){wynik:=i;} } Max := maximum(1,n); Wynik := maximum(2,n);
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości5 Czy to można zrobić lepiej? Metoda polega na porównywaniu sąsiednich elementów ciągu. Elementy większe (wygrywające) przechodzą do następnej ‘rundy’
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości6 Analiza metody Każdy element, z wyjątkiem maksymalnego przegrał co najwyżej raz. Element drugi co do wielkości przegrał jedynie z elementem maksymalnym. Wśród elementów, które grały z największym! Por. przykład
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości7 Koszt algorytmu „Turniej” Krok1. Zbudowanie drzewa turnieju. Załóżmy, że n= 2 k. Krok 2. Wybranie elementu drugiego największego. lg n -1 A ile elementów przegrało z największym? Tyle, ile było ‘rund’! n -1 porównań T(n)= n + lg n -2
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości8 Podstawowe struktury danych Algorytmy + struktury Danych = Programy e1, e2, e3,..., en początekkoniec Operacje na listach Pobranie elementu z listy. Wstawianie elementu na listę. Usuwanie elementu z listy. top push pop rear inject eject Operacje na lewym końcu listy Operacje na prawym końcu listy
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości9 Stos i jego własności push(s, e) = (e, e 1,e 2,..., e n ) pop(s) = (e 2,..., e n ) o ile n>1 top(s) = e 1 empty(s) wttw n=0 s = (e 1,e 2,..., e n ) top(push(s,e)) = e pop(push(s,e))= s not empty(s) => push(pop(s),top(s))=s Istnieje i takie że empty(pop i (s)) element3 next element1 next element2 next ogniwo
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości10 Struktura danych dla algorytmu ‘Turniej’ Następny element głównej listy Lista elementów, które przegrały z e (kandydaci do drugiego miejsca) e’ e” w next stosp OGNIWO listy a next stosp
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości11 Algorytm ‘Turniej’ for i := 1 to n div 2 do if e[i] < e[i+1] then L:=push(i,L); L.stosp := push(i+1, L.stosp); else L:= push(i+1, L); L.stosp := push(i, L.stosp); fi; od; Tworzenie wyników pierwszej rundy i+3 i+2 i i+1 L e[i]e[i+1]e[i+2]e[i+3]... k l Wkładam na stos element, który przegrał.
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości12 Budowa drzewa turnieju while not empty(L) do x := L; while not empty(x) do y := x.next; if e[x.w] > e[y.w] then x.stosp := push (x.stosp, y.w) else y.stosp := push(y.stosp, x.w); x.w := y.w; x.stosp := y.stosp fi; x.next := y.next; x := x.next od od; Dołącz y do elementów, które przegrały z x Dołącz x do elementów, które przegrały z y Rozważmy pierwszy element następnej pary xy
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości13 III etap - przeszukiwanie stosu { Pom := L.stos; drugi := pom.w; pom :=pop(pom); while not empty(pom) do if e[drugi ] < e[top(pom)] then drugi := top(pom) fi; pom := pop(pom); od }
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości14 Twierdzenie Algorytm Turniej jest optymalnym algorytmem pozwalającym znaleźć drugi co do wielkości element ciągu.
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości15 K-ty największy Problem: Dany jest ciąg n-elementów pewnej przestrzeni liniowo uporządkowanej. Znaleźć k-ty największy element tego ciągu.. 2, 4, 6, 12, 78, 45, 3, 33, 17, 22 Element największy = 78 element drugi co do wielkości = 45 3-ci największy = 33 4-ty największy = 22
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości16 Pierwsze rozwiązanie Krok1. Wyszukaj element e[max] największy wśród elementów e[i],...,e[n]; Krok 2. Zamień elementy na pozycjach i-tej i max. Krok 3. Powtórz postępowanie dla następnego i. T(n) = (n-1) + (n-2) (n-k) = k*n - k*(k+1)/2
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości17 Algorytm naiwny Zakładam, że elementy w ciągu e nie powtarzają się. { x := 1; while x k do max := x; for i := x+1 to n do if e[i] > e[max] then max := i fi od; swap(e[x], e[max]); x := x+1; od; wynik := e[k] } e[1]>...>e[x-1] >{e[x],...,e[n] } e[max] {e[x],...,e[n]} e[1]>...>e[x-1] >{e[x],...,e[n] }
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości18 Czy można zrobić to taniej? Rozdziel wszystkie elementy na większe od pewnego elementu M(część starsza) i na mniejsze od M (część młodsza). M = mediana Umieść medianę tak by oddzielała cześć młodszą od starszej. Wynikiem jest mediana, jeśli w części starszej jest tylko k-1 elementów. W przeciwnym przypadku: jeśli elementów starszych jest >k-1, to szukaj k-tego elementu w części starszej. Jeśli elementów starszych jest mniej niż k-1, to szukaj elementu k-(liczba elementów starszych+1) wśród elementów młodszych.
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości19 Przykład W podanym ciągu szukamy 7tego co do wielkości elementu mediana Część młodsza Część starsza mediana Część młodsza Część starsza Szukam 4-go największego Wynikiem jest element 5
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości20 Algorytm Hoare function Hoare(l, p, k) { j := SPLIT(l, p); if ( p-j = k-1) then wynik := e[j] else if p-j>k-1 then Hoare(j+1, p, k) else Hoare(l,j-1, k-(p-j+1)) fi fi } {e[1]...,e[j-1]}< e[j]<{e[j+1],...,e[n]} K-ty największy znajduje się wśród elementów e[j+1],... e[p] K-ty największy znajduje się wśród elementów e[l],... e[j-1] Zakładam, że elementy w ciągu nie powtarzają się i, że algorytm zwraca jako wynik wartość k-tego największego elementu.
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości21 Algorytm rozdzielania int function SPLIT(l,p){ mediana := e[l]; i := l+1; j := p; while (j > i ) do while (e[j]> mediana ) do j := j-1 od; while (e[i] < mediana) do i := i+1 od; If (i<j) then swap(e[i], e[j]); i := i+1; j := j-1; fi od; swap(e[l],e[j]); return j; } ( i, l< i <j) e[i] < e[j] ( i, j < i p) e[j] e[i]
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości22 Jak to działa? 10, 5, 9, 8, 14, 7, 12, 3, 11 ij mediana , 5, 9, 8, 3, 7, 12, 14, 11 i j mediana 10, 5, 9, 8, 3, 7, 12, 14, 11 ij 7 10 i < j i > j
27 marca 2002G. Mirkowska, ASD_04 k-ty co do wielkości23 Koszt algorytmu Hoare Każdy element jest co najwyżej raz porównywany z medianą. Koszt algorytmu SPLIT Czyli T(SPLIT, n ) = n-1 = (n) W( n,k) = n-1 +W( n-1,k) Czyli W(n,k)= k*n – k(k+1)/2 A(n,k) = (n-1) + 1/n[ j=1...n-k A(n-j, k) + j=n-k+2... n A(j-1,k – (n-j+1)] Szukanie w części starszejSzukanie w części młodszej A(n,k) = O(n)