Zbiory dynamiczne.

Slides:



Advertisements
Podobne prezentacje
ALGORYTMY I STRUKTURY DANYCH
Advertisements

Wstawianie i wyszukiwanie kluczy w tablicach i drzewach binarnych
PRAM.
STRUKTURY DANYCH.
Sortowanie przez scalanie
Algorytmy sortowania i porządkowania
Algorytmy sortowania i przeszukiwania
Algorytmy – c.d. złożoność algorytmów struktury danych
Schemat blokowy M START KONIEC
Zaawansowane techniki algorytmiczne
ALGORYTMY GRAFOWE.
Dynamiczne struktury danych Listy, Kolejki, Stosy
Grażyna Mirkowska PJWSTK 15 listopad 2000
Wykład 6 Najkrótsza ścieżka w grafie z jednym źródłem
PROGRAMOWANIE STRUKTURALNE
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
Elementarne struktury danych Piotr Prokopowicz
Ciągi de Bruijna generowanie, własności
Współprogramy III Ten wykład ma na celu pokazanie kolejnej ciekawej możliwości, którą oferują współprogramy. Wspólprogramy reprezentujące wyrażenia regularne.
Współprogramy II W tym wykładzie pogłębimy naszą znajomość z współprogramami. Omówimy współpracę procedur rekurencyjnych i współprogramów, wprowadzimy.
pseudokody algorytmów
Sortowanie Zajęcia 13.
ZŁOŻONOŚĆ OBLICZENIOWA
ALGORYTMY GEOMETRYCZNE.
WYKŁAD 7. Spójność i rozpięte drzewa
Model danych oparty na listach
Dynamiczne struktury danych 1
Algorytmy grafowe Reprezentacja w pamięci
Semantyki programów współbieżnych " Determinizm programów sekwencyjnych, " Nie-determinizm programów współbieżnych, " prawdziwa równoległość vs.przeploty.
dr Anna Kwiatkowska Instytut Informatyki
FP-Growth Adam Pieśkiewicz Kamil Niezręcki Krzysztof Grześkowiak
WYKŁAD 7. Spójność i rozpięte drzewa Graf jest spójny, gdy dla każdego podziału V na dwa rozłączne podzbiory A i B istnieje krawędź z A do B. Definicja.
Algorytmy i struktury danych
Algorytmy i struktury danych
Zbiór do posortowania mieści się w pamięci
Podstawy programowania II
Operacje na strukturach listowych
Sortowanie przez kopcowanie
DRZEWA BINARNE Emilia Krukowska.
Algorytmy i struktury danych
Geometria obliczeniowa Wykład 4
Złożone typy danych Listy Tworzenie elastycznych baz danych
Materiały pochodzą z Platformy Edukacyjnej Portalu
ALGORYTMY ROZWIĄZYWANIA GIER C.D.
Tablice w Turbo Pascalu.
Sortowanie tablic jednowymiarowych
Dynamiczne struktury danych
IV EKSPLORACJA DANYCH Zadania eksploracji danych: klasyfikacja
Algorytmy i Struktury Danych
Powtórzenie wyk ł adu 10 Fizyczna organizacja danych w bazie danych. Indeksy.
WYKŁAD 06 Programowanie dynamiczne Grażyna Mirkowska.
Algorytmy i Struktury Danych Struktury Danych
Algorytmy i Struktury Danych Drzewa BTS, AVL
Algorytmy równoległe Algorytm równoległy pozwala na wykonywanie w danej chwili więcej niż jednej operacji. EREW - wyłączny odczyt i wyłączny zapis; CREW.
Teoretyczne Podstawy Informatyki - Rok I - kierunek IS w IFAiIS UJ – 2006/ /11/2006Prof. dr hab. Elżbieta Richter-Wąs Wykład 6 Model danych oparty.
Projektowanie i programowanie systemów informatycznych W. Bartkiewicz Wykład 6. Indeksowanie plików – Indeksy drzewiaste ISAM i drzewa B+
ALGORYTMY I STRUKTURY DANYCH
Indeksy drzewiaste. ISAM ISAM - INDEXED SEQUENTIAL ACCESS METHOD Problem: –Dany jest plik uporządkowany – w jaki sposób zrealizować efektywnie zapytanie.
Rozdział 5 REKURENCJA.
Listy.
Kolejka priorytetowa.
Drzewa.
Zbiory rozłączne.
Współprogramy II W tym wykładzie pogłębimy naszą znajomość z współprogramami. Omówimy współpracę procedur rekurencyjnych i współprogramów, wprowadzimy.
Algorytmy i struktury danych
Algorytmy i struktury danych
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
Zapis prezentacji:

Zbiory dynamiczne

Zbiór dynamiczny Zbiór dynamiczny to zbiór wartości pochodzących z pewnego określonego uniwersum, którego zawartość zmienia się w trakcie działania programu. Elementy zbioru dynamicznego musimy co najmniej umieć porównać pod względem identyczności (czy dwa elementy są równe albo różne).

Dynamiczne struktury danych Dynamiczna struktura danych, to struktura danych pozwalająca na przechowywanie zbioru dynamicznego; rozmiar tej struktury dostosowuje się do rozmiaru danych. W zbiorze dynamicznym musimy umieć realizować operację dodania nowego elementu do zbioru i usunięcia ze zbioru wskazanego elementu. Tablica dynamiczna jest dynamiczną strukturą danych. Zastosowanie: przechowywanie pewnego zbioru danych, którego zawartość będzie się zmieniać w trakcie pracy programu.

Słownik Słownik (ang. dictionary) to struktura danych pozwalająca efektywnie realizować następujące operacje: insert(x) – dodanie nowego elementu x do zbioru dynamicznego, delete(x) – usunięcie elementu o wartości x ze zbioru dynamicznego, search(x) – sprawdzenie czy w zbiorze dynamicznym znajduje się element o wartości x. Multizbiór to zbiór dynamiczny, w którym mogą się powtarzać elementy o takich samych wartościach. Struktura danych jest homogeniczna, jeśli składa się z elementów tego samego typu.

Listy

Lista Lista (ang. list) to homogeniczna struktura danych służąca do reprezentowania zbioru dynamicznego, w której elementy ułożone w ciąg. Element listy nazywa się węzłem (ang. node); każdy węzeł zawiera pole info służące do przechowywania wartości z pewnego określonego uniwersum oraz pole next ze wskaźnikiem na następny element listy (ostatni element listy ma w polu next wpisany wskaźnik pusty). Pierwszy węzeł listy jest nazywany głową (ang. head) albo początkiem listy. Dostęp do elementów listy jest sekwencyjny – a więc dojście do elementu k-tego wymaga przejścia przez kolejne elementy listy od pierwszego do docelowego. Zastosowanie: lista najlepiej nadaje się do danych, które będą przetwarzane sekwencyjnie.

Lista Lista jednokierunkowa (ang. single linked list) to lista, po której można się poruszać tylko od głowy do ogona – w każdym węźle jest tylko wskaźnik do następnika. Lista dwukierunkowa (ang. double linked list) to lista, po której można się poruszać w obu kierunkach: w stronę głowy i w stronę ogona – w każdym węźle są dwa wskaźniki next do następnika i prev do poprzednika.

Lista Lista cykliczna to lista, w której ostatni węzeł posiada wskaźnik do pierwszego węzła. Lista dwukierunkowa może być cykliczna. Lista z wartownikiem to lista, w której na końcu umieszczony jest węzeł zwany wartownikiem – wartownik nie przechowuje danych, pełni rolę pomocniczą w nawigacji po liście. Lista z wartownikiem może być cykliczna lub dwukierunkowa. Gdy dane pochodzą z uniwersum z porządkiem liniowym, to dane w liście można przechowywać w sposób uporządkowany – mamy w tedy do czynienia z listą uporządkowaną.

Lista Wyszukiwanie wartości w liście – wersja iteracyjna Search(wezeł *w, x) -> boolean { while (w.info != x) { if (w.next != null) w := w.next; else return false; } return true; Czas: O(n) gdzie n to ilość elementów na liście Pamięć: O(1)

Lista Wyszukiwanie wartości w liście – wersja rekurencyjna Search(wezeł *w, x) -> boolean { if (w == null) return false; if (w.info == x) return true; return Search(w.next, x); } Czas: O(n) gdzie n to ilość elementów na liście Pamięć: O(n) zależy od liczby wywołań rekurencyjnych

Lista Wyszukiwanie wartości w liście posortowanej – wersja rekurencyjna Search(wezeł *w, x) -> boolean { if (w == null) return false; if (w.info == x) return true; if (w.info > x) return false; return Search(w.next, x); } Czas: O(n) gdzie n to ilość elementów na liście Pamięć: O(n) zależy od liczby wywołań rekurencyjnych

Lista Wstawianie elementu do listy nieuporządkowanej: na początek listy, na koniec, na zadaną pozycję. Wstawianie elementu do listy uporządkowanej Usuwanie elementu z listy: usuwanie elementu z zadanej pozycji, usuwanie elementu o zadanej wartości.

Listy Technika zwracania wskaźnika do struktury po zmodyfikowaniu. Przykład: wstawienie elementu na zadaną pozycję: insert(węzeł *w, x, pos) -> węzeł* { if (pos < 0) error; if (w == null and pos > 0) error; if (pos > 0) { w.next := insert(w.next, x, pos-1); return w; } else return new węzeł(x, w); } wywołanie: head := insert(head, x);

Listy Operacje słownikowe na liście n- elementowej wymagają: czasu O(n), pamięci O(1) gdy używamy iteracji albo O(n) gdy korzystamy z rekurencji.

Listy Zadanie: podział listy na dwie równe podlisty (z dokładnością do 1 elementu). Rozwiązanie: dwa wskaźniki, jeden robi podwójne skoki, drugi pojedyncze; po dotarciu na koniec listy pierwszego wskaźnika, drugi wskazuje na węzeł środkowy. split(węzeł *h) -> (węzeł*, węzeł*) { węzeł *p = head; węzeł *q = head; if (p == null) return (null, null); while (q != null) { q := q.next; if (q == null) break; q := q.next; if (q != null) p := p.next; } q := p.next; p.nex; := null; return (head, q); }

Listy Zadanie: należy scalić dwie posortowane lisy . Rozwiązanie: do końca listy wynikowej doczepiamy mniejszy spośród głów pozostałych list. merge(węzeł *g, węzeł *h) -> węzeł* { if (g == null) return h; if (h == null) return g; węzeł *r = g; if (g.info < h.info) g := g.next; else { r := h; h := h.next; } węzeł *s = r; while (g != null and h != null) if (g.info < h.info) { r.next := g; r := r.next; g := g.next; } else { r.next := h; r := r.next; h := h.next; } if (g != null) r.next := g; else r.next := h; return s; }

Zadanie 1 Zdefiniuj klasę reprezentującą węzeł listy jednokierunkowej wraz z operacjami wstawiania nowego elementu na zadaną pozycję, usuwania węzła z zadanej pozycji i sprawdzania czy określony element znajduje się na liście (operacje te zaimplementuj rekurencyjnie). Węzeł listy zdefiniuj jako szablon przy pomocy template<typename T>.

Zadanie 2 Zdefiniuj klasę reprezentującą listę jako opakowanie dla struktury zbudowanej na węzłach. W klasie tej opakuj metodę wstawiającą do listy, usuwającą z listy i sprawdzającą czy element występuje na liście. Dodatkowo dopisz metody: wstawiająca element na początek listy, na koniec listy, usuwającą pierwszy i usuwającą ostatni element na liście. Listę zdefiniuj jako szablon przy pomocy template<typename T>.

Zadanie 3 Zdefiniuj klasę reprezentującą węzeł listy jednokierunkowej uporządkowanej wraz z operacjami wstawiania nowego elementu, usuwania elementu i sprawdzania czy określony element znajduje się na liście. Zdefiniuj też klasę reprezentującą listę jako opakowanie dla struktury zbudowanej na węzłach. Węzeł listy oraz listę zdefiniuj jako szablony przy pomocy template<typename T>.

Drzewa

Drzewa Drzewo (ang. tree) to zbiór węzłów powiązanych wskaźnikami, bez cykli. Drzewo ukorzenione – posiada wyróżniony węzeł początkowy zwany korzeniem (ang. root). Drzewo jest strukturą hierarchiczną – analogia do polskich jabłek na rozgałęzionej jabłoni. Korzeń węzła znajduje się na poziomie 0; numer poziomu danego węzła w drzewie jest wyznaczony odległością krawędziową od korzenia. Liściem w drzewie (ang. leaf) jest węzeł bez żadnego następnika. Węzeł wewnętrzny posiada co najmniej jednego następnika.

Drzewa Wysokość drzewa – długość najdłuższej ścieżki od korzenia do liścia (liczba węzłów) – inaczej liczba poziomów na których zapisane jest drzewo. Głębokość węzła – długość ścieżki od korzenia do tego węzła (liczba węzłów) – inaczej numer poziomu na którym znajduje się węzeł. Uwaga: poziomy w drzewie numerujemy od 0; korzeń znajduje się na poziomie 0.

Drzewo Drzewo uporządkowane ma ponumerowanych (oznaczonych) następników – ich kolejność w takim drzewie jest istotna. Drzewo k-arne to drzewo uporządkowane, które posiada co najwyżej k następników. Drzewo binarne – może posiadać dwóch następników: lewego i prawego.

Reprezentacja drzew uporządkowanych „na lewo syn na prawo brat”

Drzewo BST Drzewo BST to drzewo binarne, w którym przechowujemy elementy z pewnego uniwersum z porządkiem liniowym i w drzewie tym jest zachowany porządek symetryczny. W drzewie binarnym jest zachowany porządek symetryczny, gdy elementy mniejsze od korzenia znajdują się w lewym poddrzewie, elementy większe od korzenia w prawym poddrzewie oraz w lewym i w prawym poddrzewie też jest zachowany porządek symetryczny.

Drzewo BST Wyszukiwanie w drzewie BST – działa tak jak w wyszukiwaniu binarnym serach (węzeł *w, x) -> boolean { if (w == null) return false; if (x < w.info) return search(w.left, x); else if (w.info < x) then return search(w.right, x); else return true; }

Drzewo BST Element minimalny znajduje się najbardziej po lewej stronie w drzewie BST – od korzenia poruszamy się ciągle w lewo, ostatni węzeł na lewej ścieżce zawiera minimum. Element maksymalny znajduje się najbardziej po prawej stronie w drzewie BST – od korzenia poruszamy się ciągle w prawo , ostatni węzeł na prawej ścieżce zawiera maksimum.

Drzewo BST Wstawienie nowego elementu do drzewa BST – znajdujemy mu miejsce tak jak w wyszukiwaniu binarnym (aż dojdziemy do wskaźnika pustego) insert (węzeł *w, x) -> node* { if (w == null) return new node(x); if (x < w.info) w.left := insert(w.left, x); else if (w.info < x) then w.right := insert(w.right, x); else w.info := x; return w; }

Drzewo BST Usunięcie elementu z drzewa BST – znajdujemy miejsce tego elementu tak jak w wyszukiwaniu binarnym (jak dojdziemy do wskaźnika pustego to elementu nie ma w drzewie): gdy element jest w liściu, to odcinam liść; gdy element jest w węźle z jednym następnikiem, to usuwam ze ścieżki ten węzeł; gdy element jest w węźle z dwoma synami, to z prawego poddrzewa usuwamy minimum (albo z lewego poddrzewa usuwamy maksimum) i przenosimy je do tego węzła.

Przeglądanie drzew BST In-order – najpierw jest przeglądane i przetwarzane lewe poddrzewo w porządku in-order, potem korzeń a na końcu prawe poddrzewo w porządku in-order. Przeglądanie drzewa BST w porządku in- order gwarantuje, że węzły tego drzewa zostaną przetworzone w kolejności od najmniejszej do największej wartości. Przeglądanie in-order można wykorzystać do sortowania danych.

Przeglądanie drzew BST Pre-order – najpierw jest przeglądany i przetwarzany korzeń drzewa, potem lewe poddrzewo w porządku pre-order a na końcu prawe poddrzewo w porządku pre-order. Przeglądanie drzewa BST w porządku pre-order gwarantuje, że na początku będą przetworzone węzły z lewej ścieżki tego drzewa w kolejności od korzenia do węzła o najmniejszej wartości. Post-order – najpierw jest przeglądane i przetwarzane lewe poddrzewo w porządku post-order, potem prawe poddrzewo w porządku post-order a na końcu korzeń drzewa. Przeglądanie drzewa BST w porządku post-order gwarantuje, że na końcu będą przetworzone węzły z prawej ścieżki tego drzewa w kolejności od węzła o największej wartości do korzenia.

Struktura drzew BST Wysokość drzewa – liczba poziomów zajmowanych przez drzewo (korzeń znajduje się na poziomie 0, na ostatnim poziomie znajdują się tylko liście) – albo długość wierzchołkowa najdłużej ścieżki od korzenia do liścia . Głębokość węzła – numer poziomu na którym znajduje się dany węzeł – albo krawędziowa odległość od korzenia. Wysokość drzewa n-elementowego jest nie mniejsza niż log(n) i nie większa niż n.

Struktura drzew BST Drzewo regularne to drzewo binarne, w którym każdy węzeł wewnętrzny na dwóch synów. Drzewo pełne to drzewo regularne, w którym wszystkie liście są na tym samym poziomie. Drzewo pełne o wysokości h ma 2h-1 węzłów. Drzewo zupełne to drzewo pełne, z którego usunięto część liści z prawej strony. Drzewo zupełne o wysokości h ma od 2h-1 do 2h-1 węzłów.

Rotacje w drzewie BST W dowolnym wewnętrznym węźle drzewa BST można zrobić rotację (w lewo albo w prawo) i nie zostanie zniszczony porządek symetryczny w tym drzewie.

Zadanie 1 Zdefiniuj klasę reprezentującą węzeł drzewa BST wraz z operacjami wstawiania nowego elementu, usuwania elementu i sprawdzania czy określony element znajduje się w drzewie. Węzeł drzewa zdefiniuj jako szablon przy pomocy template<typename T>.

Zadanie 2 Zdefiniuj klasę reprezentującą drzewo BST jako opakowanie dla struktury zbudowanej na węzłach. W klasie tej opakuj metodę wstawiającą do drzewa, usuwającą z drzewa i sprawdzającą czy element występuje w drzewie. Dodatkowo dopisz metody: wyznaczające oraz usuwające najmniejszy i największy element w drzewie. Drzewo BST zdefiniuj jako szablon przy pomocy template<typename T>.