• Nie Znaleziono Wyników

ALGORYTMY I STRUKTURY DANYCH

N/A
N/A
Protected

Academic year: 2021

Share "ALGORYTMY I STRUKTURY DANYCH"

Copied!
23
0
0

Pełen tekst

(1)

ALGORYTMY I STRUKTURY DANYCH

WYKŁAD 04 k-ty co do wielkości. Stosy Grażyna Mirkowska

PJWSTK, ITN semestr letni 2002

(2)

Plan wykładu

Wyszukiwanie 2-go co do wielkości elementu

– Algorytm naiwny

– Jak poprawić algorytm naiwny – Struktura danych - stos

k-ty co do wielkości

– Algorytm Hoare

– Rekursja czy stos?

(3)

Drugi największy element

Problem Dany jest ciąg e elementów e[1],...,e[n] pewnej przestrzeni liniowo uporządkowanej < E,  >. 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]})

(4)

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<= n; i++){

if (e[i]>e[max]){max:=i;}

}

wynik := 2;

for ( i =3; i<= n; i++){

if (e[i]>e[wynik]){wynik:=i;}

}

Max := maximum(1,n);

Wynik := maximum(2,n);

(5)

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

2 3

4 5 7 8 1 6

4 5 8 6

5 8

(6)

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

(7)

Koszt algorytmu „Turniej”

Krok1. Zbudowanie drzewa turnieju.

Załóżmy, że n= 2k.

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ń

(8)

Podstawowe struktury danych

Algorytmy + struktury Danych = Programy e1, e2, e3, ..., en

początek koniec

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

(9)

Stos i jego własności

< S  E, push, pop, top, empty>

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

element3

next

element1

next

element2

next

ogniwo

(10)

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

stospnext

(11)

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 L i+1

e[i] e[i+1]e[i+2]e[i+3]

...

k

l

...

Wkładam na stos element, który przegrał.

(12)

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

x y

(13)

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

}

(14)

Twierdzenie

Algorytm Turniej

jest optymalnym algorytmem pozwalającym znaleźć

drugi co do wielkości

element ciągu.

(15)

K-ty największy

Problem: Dany jest ciąg n-elementów pewnej przestrzeni liniowo uporządkowanej <E,  >.

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

(16)

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

(17)

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

(18)

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.

(19)

Przykład

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

W podanym ciągu szukamy 7tego co do wielkości elementu

mediana

Część młodsza 5 7 9 4 3 2 6 1

Część starsza 11 12

10

5 7 9 4 3 2 6 1 mediana

Część młodsza 4 3 2 1

Część starsza 7 9 6

5

Szukam 4-go największego

(20)

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.

(21)

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

(i, l< i <j) e[i] < e[j]

(i, j < i  p) e[j]  e[i]

(22)

Jak to działa?

10, 5, 9, 8, 14, 7, 12, 3, 11

i j

mediana

14 3

10, 5, 9, 8, 3, 7, 12, 14, 11

i j

mediana

10, 5, 9, 8, 3, 7, 12, 14, 11

7 10

i < j

i > j

(23)

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 starszej Szukanie w części młodszej

Cytaty

Powiązane dokumenty

Dla dodatniej liczby naturalnej n znaleźć wzór na największą potęgę liczby pierwszej p dzielącą n!4. Rozłożyć na czynniki pierwsze

mo»e by¢ zapisana jako iloczyn k rozª¡cznych cykli, których wyrazy ª¡cznie wyczerpuj¡.. zbiór {1,

Można wykazać, (dowód pomijamy; wymaga on policzenia pewnego wyznacznika typu Vandermon- de’a), że te rozwiązania są istotnie liniowo niezależne, czyli że każde

Zbiór funkcji nieparzystych oznaczymy literą N, natomiast zbiór funkcji parzystych - literą P..

Wypisać wszystkie elementy ciała Z 3 (α) oraz obliczyć sumy i iloczyny wybranych elementów tego ciała.. (16) Zbudować ciało 4-elementowe oraz ciało 9-elementowe jako

[∗∗] Wiemy, że dolna granica na liczbę wykonywanych porównań przez dowolny algorytm znajdujący minimum w n–elementowym zbiorze wynosi n − 1.. Dolna granica na

[∗∗] Wiemy, że dolna granica na liczbę wykonywanych porównań przez dowolny algorytm znajdujący minimum w n–elementowym zbiorze wynosi n − 1.. Dolna granica na

Jeśli graf G jest planarny, to zawiera wierzchołek stopnie niewi ekszego