Algorytmy i struktury danych

Transkrypt

Algorytmy i struktury danych
Algorytmy i struktury danych
ĆWICZENIE 2 - WYBRANE ZŁOŻONE STRUKTURY DANYCH - (12.03.2012)
Prowadząca: dr hab. inż. Małgorzata Sterna
Informatyka i3, poniedziałek godz. 11:45
Adam Matuszewski, nr 106550
Oliver Kostera , nr 106552
1.Tworzenie struktury danych
Czas (w sekundach) tworzenia struktury
2
1,8
1,6
Czas [s]
1,4
1,2
1
cB
0,8
cL
0,6
cTR
0,4
cTB
0,2
0
Liczba elementów
Rozmiar
50000
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
1500000
cL
0,01
0,01
0,01
0,03
0,02
0,04
0,04
0,06
0,06
0,09
0,08
0,14
cTB
0,01
0,03
0,05
0,08
0,11
0,12
0,16
0,18
0,22
0,25
0,28
0,42
cB
0,01
0,03
0,07
0,11
0,15
0,19
0,23
0,28
0,32
0,36
0,4
0,62
cTR
0,02
0,05
0,16
0,28
0,41
0,54
0,7
0,81
1,06
1,09
1,39
1,78
Najszybciej powstaje lista jednokierunkowa, zdecydowanie najwolniej jako drzewo
poszukiwań binarnych TR. Podczas budowy drzewa następuje wiele porównań przez co ma złożoność
O(n*log2n). Tworzenie listy ma złożoność O(n). Tworzenie drzewa TR trwa dłużej niż tworzenie
drzewa TB, ponieważ drzewo TR jest wyższe(oprócz wypadku optymistycznego – wtedy jest takie
same), a zatem znalezienie miejsc, w które należy wstawić kolejne elementy wymaga większej liczby
porównań.
2. Wyszukiwanie w strukturach danych
Czas wyszukiwania wszystkich elementów w standardowej tablicy i na liście:
12000
10000
Czas [s]
8000
6000
ssB
4000
sL
2000
0
Liczba elementów
Czas (w sekundach) wyszukiwania wszystkich elementów w tablicy połówkowej i drzewach:
2
1,8
1,6
1,4
Czas [s]
1,2
1
sbB
0,8
sTR
0,6
sTB
0,4
0,2
0
Liczba elementów
Rozmiar
sTB
sTR
sbB
ssB
sL
50000
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
0,01
0,03
0,09
0,16
0,23
0,3
0,39
0,46
0,56
0,63
0,74
0,02
0,04
0,14
0,25
0,38
0,5
0,65
0,81
1,01
1,09
1,31
0,02
0,03
0,09
0,16
0,26
0,37
0,55
0,63
0,77
0,97
1,15
8,03
31,98
128,22
290,2
516,92
809,01
1166,45
1588,35
2075,25
2626,33
3243,45
8,99
42,67
189,27
453,72
812,98
1312,12
2015,37
2892,59
3845,18
4648,45
6095,72
1500000
0,99
1,78
1,9
7298,27
11127,9
Algorytmy wyszukiwania elementu w tablicy i w liście działają na bardzo podobnej zasadzie,
porównują kolejne elementy z wartością szukaną, dopóki jej nie znajdą, przez co czas działania
wydłuża się. Wyszukiwanie w tablicy okazało się jednak szybsze, być może dlatego że bezpośrednie
odwołanie do elementu może zajmować mniej czasu niż odwołanie poprzez poprzedni element na
liście.
Algorytmy wyszukiwania połówkowego w tablicy i wyszukiwania w drzewie TB również
działają na podobnej zasadzie - korzystamy z uporządkowania elementów w strukturze tzn. jeśli
bieżący element jest większy(mniejszy) od szukanego elementu, kontynuujemy szukanie tylko dla
elementów mniejszych(większych) od bieżącego. Pozwala to na zmniejszenie złożoności do
O(n*log2n). Wyszukiwanie połówkowe w tablicy przebiega jednak wolniej, gdyż wymaga
każdorazowego wyliczania indeksu, pod którym znajdziemy kolejny porównywany element, podczas
gdy węzły drzewa zawierają do niego bezpośredni wskaźnik.
Czas [s]
3. Wysokość drzew poszukiwań binarnych
500
450
400
350
300
250
200
150
100
50
0
hTB
hTR
Liczba elementów
Rozmiar
50000
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
1500000
hTB
16
17
18
19
19
19
20
20
20
20
20
21
hTR
111
101
128
139
265
195
283
144
380
255
434
413
Wysokość drzewa TR jest znacznie większa niż wysokość drzewa TB. Wprowadzenie danych w
kolejności wynikającej z dzielenia połówkowego tablicy posortowanej umożliwia nam stworzenie
drzewa o wysokości 1+log2n, czyli drzewa wyważonego (TB). Gdybyśmy umieszczali posortowane
dane wg tablicy B to drzewo składałoby się z jednej długiej gałęzi. Wysokość takiego drzewa byłaby
równa n. W przypadku drzewa TR dane wprowadzane są losowo a jego wysokość zawiera się w
przedziale od 1+log2n do n. Wysokość jest zależna od danych.
Wysokość drzewa poszukiwań binarnych jest bardzo istotna, gdyż reguluje czas wykonywania
podstawowych operacji na tej strukturze, takich jak wyszukiwanie bądź dodawanie nowego
elementu. Aby np. odszukać w drzewie konkretny element musimy bowiem przejść całą ścieżkę od
korzenia, aż do tego elementu, wykonując przy tym tyle porównań ile wynosi długość ścieżki.
Wysokość drzewa będzie więc oznaczała maksymalną liczbę porównań które musimy wykonać żeby
znaleźć szukany element. Im niższe drzewo tym mniej porównań, krótszy czas wykonywania operacji i
korzystniejsza struktura.
4.Wady i zalety
Złożoność pamięciowa wszystkich struktur jest taka sama i jest O(n). Jednak elementy tablicy
zawierają jedynie wartość danej, element listy zawiera dane i wskaźnik, zaś element drzewa dane
oraz dwa wskaźniki.
Tablice:
+ bezpośredni dostęp do elementów
+ łatwa implementacja – gotowa struktura
+ szybkie tworzenie (złożoność O(n), wydłuża się dla tablicy posortowanej)
+ krótki czas wyszukiwania na zasadzie dzielenia połówkowego (wymaga posortowania)
+ najmniejsze wymagania pamięciowe
- najdłuższy czas wyszukiwania elementu (dla prostego wyszukiwania, złożoność O(n))
- niewielka elastyczność (trudno dodać bądź usunąć element, zmienić rozmiar tablicy itp.)
Lista jednokierunkowa:
+ wysoka elastyczność (łatwe dodawanie i usuwanie elementów, zmienianie rozmiaru listy itp.)
+ łatwa implementacja – lecz brak gotowej struktury
+ najkrótszy czas tworzenia (złożoność O(n))
- długi czas wyszukiwania elementu (złożoność O(n))
- nienaturalny dostęp do elementów
- niełatwe sortowanie
Drzewa BST:
+ logarytmiczna złożoność wyszukiwania elementu (w przypadku pesymistycznym degraduje się do
O(n))
- średnia elastyczność (dodanie elementu wymaga wielu operacji porównania, usunięcie też może
być skomplikowane)
- nienaturalny dostęp do elementów
- najtrudniejsza implementacja(lecz nadal dość łatwa)
- dłuższy czas tworzenia (szczególnie dla posortowanych danych, złożoność od O(n*log2n) do nawet
O(n2))
- duża zależność złożoności operacji od danych wejściowych
- największe wymagania pamięciowe