• Nie Znaleziono Wyników

Wykład 10Wyszukiwanie binarne w tablicy posortowanej z powtórzeniamiAnaliza wydajności algorytmów sortowania

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 10Wyszukiwanie binarne w tablicy posortowanej z powtórzeniamiAnaliza wydajności algorytmów sortowania"

Copied!
1
0
0

Pełen tekst

(1)

Wykład 10

Wyszukiwanie binarne w tablicy posortowanej z powtórzeniami Analiza wydajności algorytmów sortowania

1. Wyszukiwanie binarne w tablicy posortowanej z powtórzeniami elementów Algorytm wyszukiwania binarnego z powtórzeniami - poziom konceptualny (1) Rozszerz N - elementowy ciąg o dowolny element skrajny lewy i dowolny

element skrajny prawy, gdzie dodane elementy nie należą do badanego ciągu (2) Dopóki badany podciąg jest niemniejszy niż 3 - elementowy, wykonuj:

(2.1) Wskaż na środkowy element wyznaczonego ciągu

(2.2) Jeśli wskazany element jest mniejszy od klucza, wyznacz podciąg prawy z włączeniem wskazanego elementu, w przeciwnym przypadku (2.3) jeśli wskazany element jest równy lub większy od klucza, wyznacz

podciąg lewy z włączeniem wskazanego elementu.

(3) Jeśli w wyznaczonym 2 - elementowym ciągu element prawy jest elementem dodanym lub element prawy jest różny od klucza, nie znaleziono elementu równego kluczowi-zwróć 0, w przeciwnym razie element prawy jest równy kluczowi – zwróć 1.

Przykład przeszukiwania binarnego z powtórzeniami - nieparzysta liczba elementów

l.p. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -3 -1 1 1 3 4 5 7 7 7 25 25 31 34 36 39 42 42 42 l.p. 20 21 22 23 24 25 26 27 28 29 30 31

46 48 48 55 55 55 61 63 66 67 74 74

12 28

4 1

8 24

14 26

10 18

2

29 27

22

25 19

17

11 13

5 7 9

3

4 3

1

1 2

4 5

8

1 21 31

20

30

3 23

16

15 6

0, 16

0, 8 8, 16

16, 32

0, 4 4, 8 8, 12 12, 16

0, 2 2, 4 4, 6 6 ,8 8, 10 10, 12 12, 14 14, 16 16, 18 18, 20 20, 22 22, 24 24, 26 26, 28 28, 30 30, 32 24, 32

16, 24

16, 20 20, 24 24, 28 28, 32

0, 1 1, 2

2, 3 3, 4

4, 5 5, 6

6, 7 7, 8

8, 9 10, 11 11, 12

12, 13 13, 14

14, 15 15, 16

16, 17 18, 19 19, 20

20, 21 21, 22

22, 23 23, 24

24, 25 26, 27 28, 29 30, 31 31, 32

17, 18 27, 28 29, 30

(2)

Przykład przeszukiwania binarnego z powtórzeniami - parzysta liczba elementów l.p. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

-3 -1 1 1 3 4 5 7 7 7 25 25 31 34 36 39 42 42 42 l.p. 20 21 22 23 24 25 26 27 28 29 30 31 32

46 48 48 55 55 55 61 63 66 67 74 74 75

12 28

4 1

8 24

14 26

10 18

2

29 27 22

25 19

17 11 13

5 7 9

3

4 3

1

1 2

4 5

8

1 21 31

20

30

3 23

16

15 6

0, 16

0, 8 8, 16

16, 33

0, 4 4, 8 8, 12 12, 16

0,2 2, 4 4, 6 6 ,8 8, 10 10, 12 12, 14 14, 16 16, 18 18, 20 20, 22 22, 24 24, 26 26, 28 28, 30 30, 33 24, 33

16, 24

16, 20 20, 24 24, 28 28, 33

32

31, 33 0, 1

1, 2 2, 3 3, 4

4, 5 5, 6

6, 7 7, 8

8, 9 9, 10

10, 11 11, 12

12, 13 13, 14

14, 15 15, 16

16, 17 18, 19 19, 20

20, 21 21, 22

22, 23 23, 24

24, 25 26, 27 28, 29

17, 18 25, 26 27, 28 29, 30

31, 32 32, 33 30, 31

W tablicach uporządkowanych dla n elementów mamy:

średnia liczba przeszukań - lg n

najgorszy przypadek przeszukań - lg n

(3)

Wyszukiwanie binarne z powtórzeniami, implementacja w C/C++

#include <conio.h>

#include <stdio.h>

typedef int element;

const long N=12;

int SzukW(long L, long P, element klucz, long& ktory, element T[]);

void wyswietl(element T[], long ile);

void main()

{ element T[N]={1,2,3,4,5,6,7,8,9,16,18,20};

element liczba;

long i, ktory, ile=12;;

clrscr();

wyswietl(T,ile);

do

{ printf("Podaj liczbe: ");

scanf("%d",&liczba);

if (SzukW(0, N-1, liczba, ktory, T))

printf("Szukana liczba ma numer %d w tablicy.\n", ktory+1);

else printf("Nie ma tej liczby w tablicy.\n");

printf("Jesli koniec, nacisnij ESC-/nie, nacisnij dowolny klawisz\n");

} while(getch()!=27);

}

int SzukW(long L, long P, element klucz, long& ktory, element T[]) { long S;

ktory=P+1;

L--;

while ((L+1) != ktory) { S = (L + ktory ) / 2;

if (T[S] < klucz) L = S;

else ktory=S; }

return !(ktory > P || T[ktory] != klucz);

}

void wyswietl(element T[], long ile) { for(long i=0; i<ile; i++)

{ printf("%d \n", T[i]);

if (i%20==0) {char z=getch();

if (z=='k') return; }}

printf("%ld \n", ile); }

(4)

2. Analiza wydajności algorytmów sortowania

1) Analiza wydajności algorytmu sortowania bąbelkowego i oraz sortowania przez kopcowanie – semestr zimowy, wykład 3 z serii INE 2000.

2) Analiza wydajności algorytmu sortowania przez łączenie i sortowania szybkiego

Uzyskiwanie asymptotycznych oszacowań rozwiązań przy zastosowaniu notacji  i O - rekurencje

Rozwiązania metodą podstawiania Przykład 1

Przykład rekurencji dla algorytmu sortowania przez łączenie

T(n) =

a) Założenia:

argumentami funkcji są liczby całkowite

czas działania algorytmu dla danych wejściowych o stałym rozmiarze jest stały, stąd przyjmuje się, że czas działania algorytmu da małych rozmiarów danych wejściowych N jest stały. Na podstawie tego założenia rekurencja dla algorytmu sortowania przez łączenie bez podawania wartości dla małych N jest następująca:

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

Metoda rozwiązywania równań rekurencyjnych przez podstawianie polega na przyjęciu postaci rozwiązania, a następnie wykazaniu przez indukcję, że jest ono poprawne. Metoda może być użyta do określenia albo górnego albo dolnego oszacowania wartości rozwiązania rekurencji.

b) Rozwiązanie rekurencji dla algorytmu sortowania przez łączenie

T(n) = 2T(n/2) + (n) T(n) = 2T( n/2 ) + n

odgadnięte rozwiązanie: T(n) = O(n lg n), należy udowodnić, że T(n)  c n lgn

rozwiązanie: T(n/2 )  (cn/2 lg (n/2 )), czyli

T(n) 2 (cn/2 lg (n/2 ))+ n cn lg(n/2)+ n= cn lgn - cnlg2+n= c n lgn - cn+n (1) , jeśli n = 1

T( n/2 )+ T( n/2 ) + (n), jeśli n > 1

(5)

T(n)  cn lg n dla c  2 i n  2.

c) Wynik: czas działania procedury sortowania przez łączenie jest równy O(n lgn).

(6)

Przykład 2 - rozwiązanie rekurencji dla algorytmu sortowania szybkiego a) przypadek pesymistyczny:

( ) max ( ( ) ( )) ( )

1

1 T q T n q n

n T

n

q

, gdzie q oznacza podział obszaru danych, z których jeden ma co najmniej 1 element.

odgadnięte rozwiązanie O(n2), stąd należy udowodnić, że T(n)  cn2

rozwiązanie T(n) 1max1(cq2 c(n q)2) (n)

n

q

cn n

cn c n

c c n q

n q c

n

T q n

2 2 2

2 2

1

1max ( ( ) ) ( ) (12 ( 1) 2 ( 1)

)

(

,

W przypadku pesymistycznym czas działania procedury sortowania szybkiego jest równy O(n2).

b) przypadek średni

T n

n T T n T q T n q n

q n

( ) ( ( ) (  ) ( ( ) ( ))) ( )

1 1 1

1

1

odgadnięte rozwiązanie O(n lgn), stąd należy udowodnić, że T(n)  an lgn + b

rozwiązanie: n1( ( )T 1 T n( 1) 1n( ( ) 1 (n21))O n( ), czyli

T n n T q T n q n

n T k n

q n

k n

( ) ( ( ) ( )) ( ) ( ) ( )

 

1 2

1 1

1

1

2

1 1

n ak k b n

k n

( lg ) ( )

 

2 2

1

1

a 1

n k k b

n n n

k n

lg ( ) ( ), gdzie zakładamy k k n n n

k n

lg lg

12 2 18 1

1

2 , gdyż k k n n n

k n

lg lg ( )

21 2 1

1

2 , czyli

k k k k k k n k n k n k k

k n k

n

k n k n

n

k n n

k n k

n

lg lg lg (lg ) lg lg

/ /

/ /

/

     

1 2 1

1 1

1 2 1

2 1

2 1

1 2 1

1 1

1

21n( n1) lgn 12 2(n1)n2 21n2lgn81n2,stąd

T n a

n n n n b

n n n

( ) 2 (1 lg ) (  ) ( ) 2

1 8

2 1

2 2  a n lgn - a4n + 2b + (n)

= a n lgn + b + (b - a4 n + (n)), czyli T(n)  a n lgn +b

W przypadku średnim czas działania procedury sortowania szybkiego jest równy O(n lgn).

(7)

Drzewa algorytmów 1) Przypadek najlepszy

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

n/2

3

4 3

1

1 2

4 5

8

n

n/2

n/4 n/4 n/4 n/4

n/8 n/8 n/8 n/8 n/8 n/8 n/8 n/8

lg n

n n

n

n

(n lg n)

...

2) Przypadek najgorszy

T(n) = T(1)+ T(n-1) + (n), gdzie T(1)= (1)

T(n) = T(n-1) +(n), czyli po zastosowaniu metody iteracyjnej

) ( ) ( ) ( )

( 2

1 1

n k

k n

T n

k n

k

 

1

3

4 3

1

1 2

4 5

8

n

n-1

1 n-2

1 n-3

n

n

n

n-1

n-2

(n 2) 1

2 3

1 1 2

(8)

3) Przypadek zrównoważony T(n) = T(n/10) + T(9n/10) + n

n/10

3

4 3

1

1 2

4 5

8

n

9n/10

n/100 9n/100 9n/100 81n/100

1 81n/1000 729n/1000

log10 n

n

n

n

n

(n lg n)

log10/9 n 1 <=n

4) Przypadek średni

Stanowi połączenie przypadku najgorszego, najlepszego i zrównoważonego i jest równy O(n lg n).

(9)

5) Wydajność algorytmów sortowania - podsumowanie (wg R. Sedgewick: Algorytmy w C++)

rodzaj\n 12500 25000 50000 100000 200000 400000 800000

szybkie 2 5 11 24 52 109 241

łączenie zstępujące

5 12 23 53 111 237 524

łączenie wstępujące

5 11 26 59 127 267 568

rodzaj\n 12500 25000 50000 100000 200000 400000 800000

szybkie 2 7 13 27 58 122 261

łączenie

zstępujące 5 11 24 52 111 238 520

kopcowanie zstępujące

3 8 18 42 100 232 547

rodzaj\n 12500 25000 50000 100000 200000 400000 800000

szybkie 2 5 10 21 49 102 223

pozycyjne od cyfry najmniej znaczącej D=16

5 8 15 30 56 110 219

pozycyjne od cyfry najbardziej znaczącej D=16

52 54 58 67 296 119398 1532492

Cytaty

Powiązane dokumenty

(3) Jeśli w wyznaczonym 2 - elementowym ciągu element prawy jest elementem dodanym lub element prawy jest różny od klucza, nie znaleziono elementu równego kluczowi-zwróć 0,

(3) Jeśli w wyznaczonym 2 - elementowym ciągu element prawy jest elementem dodanym lub element prawy jest różny od klucza, nie znaleziono elementu równego

Założenie: najefektywniejsze rozwiązanie stosu za pomocą tablicy – szczyt stosu to ostatni element wstawiony tablicy począwszy od miejsca o indeksie 0 (jeśli liczba elementów

// utworzono tablicę 10 referencji typu String, naleŜy dla kaŜdego elementu tablicy przydzielić pamięć. • Przydział pamięci na elementy

• dwa ładunki przeciwnych znaków, leżące w równych odległościach od początku układu współrzędnych mają tylko elektryczny moment dipolowy. • czysty moment

(b) w pierścieniu ideałów głównych każdy ideał pierwszy

(6) wynika z faktu, iż pomiędzy grupami sprzę- żonymi potrafimy wskazać bijekcję ustanowioną przez automorfizm wewnętrzny... Jedyna nietrywialna część uwagi to (3),

Niech punkt I będzie środkiem okręgu wpisanego w trójkąt ABC, zaś D, E, F niech będą punktami przecięcia dwusiecznych kątów A, B, C trójkąta ABC odpowiednio z bokami BC, AC