Algorytmy i struktury danych ĆWICZENIE 2 - WYBRANE ZŁOŻONE STRUKTURY DANYCH - (12.3.212) Prowadząca: dr hab. inż. Małgorzata Sterna Informatyka i3, poniedziałek godz. 11:45 Adam Matuszewski, nr 1655 Oliver Kostera, nr 16552
1.Tworzenie struktury danych Czas (w sekundach) tworzenia struktury 2 1,8 1,6 1,4 1,2 1,8,6,4,2 cb cl ctr ctb Rozmiar cl ctb cb ctr 5,1,1,1,2 1,1,3,3,5 2,1,5,7,16 3,3,8,11,28 4,2,11,15,41 5,4,12,19,54 6,4,16,23,7 7,6,18,28,81 8,6,22,32 1,6 9,9,25,36 1,9 1,8,28,4 1,39 15,14,42,62 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*log 2 n). 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: 12 1 8 6 4 2 ssb sl Czas (w sekundach) wyszukiwania wszystkich elementów w tablicy połówkowej i drzewach: 2 1,8 1,6 1,4 1,2 1,8,6,4 sbb str stb,2
Rozmiar stb str sbb ssb sl 5,1,2,2 8,3 8,99 1,3,4,3 31,98 42,67 2,9,14,9 128,22 189,27 3,16,25,16 29,2 453,72 4,23,38,26 516,92 812,98 5,3,5,37 89,1 1312,12 6,39,65,55 1166,45 215,37 7,46,81,63 1588,35 2892,59 8,56 1,1,77 275,25 3845,18 9,63 1,9,97 2626,33 4648,45 1,74 1,31 1,15 3243,45 695,72 15,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*log 2 n). 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.
3. Wysokość drzew poszukiwań binarnych 5 45 4 35 3 25 2 15 1 5 htb htr Rozmiar htb htr 5 16 111 1 17 11 2 18 128 3 19 139 4 19 265 5 19 195 6 2 283 7 2 144 8 2 38 9 2 255 1 2 434 15 21 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+log 2 n, 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+log 2 n 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*log 2 n) do nawet O(n 2 )) - duża zależność złożoności operacji od danych wejściowych - największe wymagania pamięciowe