Algorytmy i struktury danych

Slides:



Advertisements
Podobne prezentacje
ALGORYTMY I STRUKTURY DANYCH
Advertisements

PRAM.
STRUKTURY DANYCH.
Algorytmy sortowania i porządkowania
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
Minimalne drzewa rozpinające
Generowanie drzew decyzyjnych dla dużych zbiorów danych
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
Elementarne struktury danych Piotr Prokopowicz
Sztuczna Inteligencja 2.1 Metody szukania na ślepo
XPath. XSLT – część XPath. XSLT – część 12 XPath – XML Path Language Problem: –jednoznaczne adresowanie fragmentów struktury dokumentu XML.
Geometria obliczeniowa Wykład 1
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
ZŁOŻONOŚĆ OBLICZENIOWA
ALGORYTMY GEOMETRYCZNE.
Szachy komputerowe. Ogólna idea silnika szachowego.
Dynamiczne struktury danych 1
dr Anna Kwiatkowska Instytut Informatyki
FP-Growth Adam Pieśkiewicz Kamil Niezręcki Krzysztof Grześkowiak
FP-Growth Adam Pieśkiewicz Kamil Niezręcki Krzysztof Grześkowiak Michał Kucal
FP-Growth Adam Pieśkiewicz Kamil Niezręcki Krzysztof Grześkowiak Michał Kucal
ALGORYTMY I STRUKTURY DANYCH
Algorytmy i struktury danych
Algorytmy i struktury danych
Podstawy programowania II
Algorytmy i Struktury Danych Sortowanie
Operacje na strukturach listowych
Sortowanie przez kopcowanie
DRZEWA BINARNE Emilia Krukowska.
Geometria obliczeniowa Wykład 8
Algorytmy i struktury danych
Geometria obliczeniowa Wykład 3
Geometria obliczeniowa Wykład 4
PHP: warunki, pętle, switch, break, continue
Złożone typy danych Listy Tworzenie elastycznych baz danych
Materiały pochodzą z Platformy Edukacyjnej Portalu
ALGORYTMY ROZWIĄZYWANIA GIER C.D.
Geometria obliczeniowa Wykład 5
Dynamiczne struktury danych
Algorytmy i Struktury Danych
Algorytmy i Struktury Danych
Geometria obliczeniowa Wykład 5 Geometryczne struktury danych 1. Drzewa odcinków 2. Drzewa czwórkowe 3. Drzewa BSP.
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.
Sortowanie: kopce Parent(i)
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.
Zbiory dynamiczne.
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.
Geometria obliczeniowa Wykład 3
Listy.
Kolejka priorytetowa.
Drzewa.
Zbiory rozłączne.
Geometria obliczeniowa Wykład 3
Geometria obliczeniowa Wykład 5
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
Zapis prezentacji:

Algorytmy i struktury danych Drzewa ukorzenione, Drzewa wyszukiwawcze Wzbogacone drzewa, Drzewa TRIE

Drzewo ukorzenione Drzewo - każdy węzeł może mieć conajwyżej 2 lub więcej węzłów potomnych (następników), nie ma cykli Drzewo ukorzenione = drzewo z wyróżnionym jednym węzłem – korzeniem Drzewo binarne węzeł zawiera dokładnie dwa wskaźniki do węzłów potomnych Dla wygodnego trwersowania zwykle dodaje się wskaźnik do rodzica class Node: key = None data = None parent = None left = None right = None

Drzewo binarne root

Breadth First Search def BFS(node, key): "funkcja przeglada drzewo wszerz" toTraverse = Put(None, node) while toTraverse != None : toTraverse, node = Get(toTraverse) if node == None : continue #Process(node) if node.key == key: return node toTraverse = Put(toTraverse, node.left) toTraverse = Put(toTraverse, node.right) return None Brak sprawdzania czy odwiedzony?

Depth First Search def DFS(node, key): "funkcja przeglada drzewo wglab" toTraverse = Push(None, node) while toTraverse != None : toTraverse, node = Pop(toTraverse) if node == None : continue #Process(node); if node.key == key: return node toTraverse = Push(toTraverse, node.left) toTraverse = Push(toTraverse, node.right) return None Jaki jest dokładnie porządek przeglądania? Czy można go zmienić?

Depth First Search - rekursyjnie def DFSRec (node, key): """funkcja przeglada drzewo w głab – w.rekurencyjna""" if node == None: return None #Process(node) if node.key == key: return node ret = DFSRec (node.left, key) if ret != None : return ret else : return DFSRec (node.right, key)

Drzewo k-narne Drzewo k-narne węzeł zawiera co najwyżej k wskaźników do węzłów potomnych Drzewo ogólne można reprezentować przy pomocy notacji „na prawo brat, na lewo syn”

Przegladanie drzewa k-narnego class NODE: data = None sons = None # = [None, None, None ....] # fragment funkcja przeszukującej k-drzewo # stary kod toTraverse = Put(toTraverse, node.left) toTraverse = Put(toTraverse, node.right) # nowy kod for son in node.sons: toTraverse = Put(toTraverse, son)

Drzewo ogólne

Breadth First Search def BFSBrotherSon (node, key): """funkcja przeszukuje wszerz drzewo w postaci B-S"" toTraverse = Put(None, node) while toTraverse != None: toTraverse, node = Get(toTraverse) while node != None: #Process(node) if node.key == key: return node toTraverse = Put(toTraverse, node.left) node = node.right return node

Depth First Search def DFSBrotherSon (node, key): """funkcja przeszukuje wglab drzewo w postaci B-S""" toTraverse = Push(None, node) while toTraverse != None: toTraverse, node = Pop(toTraverse) while node != None: #Process(node) if node.key == key: return node toTraverse = Push(toTraverse, node.right) node = node.left return None Porządek przeglądania? Czy można go zmienić?

Depth First Search - rekursyjnie def DFSBrotherSonRec(node, key): """funkcja przeszukuje rekursyjnie wglab drzewo BS""" if node == None: return None #Process(node) if node.key == key: return node ret = DFSBrotherSonRec(node.left, key) if ret != None : return ret else: return DFSBrotherSonRec(node.right,key) Czy można zaimplementować rekurencyjnie BFSBrotherSonRec ?

Binarne drzewo poszukiwań 5 2 3 3 7 7 2 6 8 6 8 h=2 5 h=4 y=Left(x)  y.key<x.key y=Right(x)  y.key≥ x. key

Drukowanie drzewa Binarnego # funkcja wypisuje zawartość drzewa # w porządku pre-order def BSTPreorderPrint(node): if node != None : print node.key," ",node.data BSTPreorderPrint(node.left) BSTPreorderPrint(node. right) # w porządku in-order def BSTInorderPrint(node): if node != None: BSTInorderPrint(node.left) print node.key," ",node.data BSTInorderPrint(node.right)

16 10 19 5 12 17 20 1 6 14 13 15 h=4 max=20 min=1 13: 1610 12 14  13

Szukanie w drzewie BST O(h(T)) def BSTSearchRec(node, key): """Funkcja szuka klucza w BST. Moze zwrocic None jesli nie ma klucza k Wersja rekurencyjna.""" if node == None or node.key == key: return node if key < node.key: return BSTSearch(node.left, key) else: return BSTSearch(node.right, key) O(h(T))

Szukanie w drzewie BST O(h(T)) def BSTSearch(node, key): """Funkcja szuka klucza w BST. Moze zwrocic None jeśli nie ma klucza k Wersja iteracyjna.""" while node != None and node.key != key: if key < node.key : node = node.left else : node = node.right return node O(h(T))

Min/Max w drzewie BST O(h(T)) O(h(T)) #rekurencyjna wersja def BSTMinimumRec(node): if node.left == None: return node else: return BSTMinimum(node.left) #iteracyjna wersja def BSTMinimum(node): while node.left != None: node = node.left return node O(h(T)) O(h(T))

Następnik w drzewie BST # f. zwraca None jezeli node.key jest MAX def BSTSuccesor(node): if node.right != None: return BSTMinimum(node.right) tmp = node.parent while tmp != None and node == tmp.right: node = tmp tmp = tmp.parent return tmp O(h(T))

Wstawianie węzła 16 10 19 5 12 17 20 1 6 14 18 13 15 Wstawiany węzeł jest zawsze liściem Postępuj tak jak przy szukaniu. Przy napotkaniu NULL wstaw nowy węzeł.

Wstawianie do drzewia BST def BSTInsertNode (root, node): if root == None : node.parent = None node.left = None node.right = None return node tmp = root # i.e. root != None while tmp!= None: parent = tmp if node.key < tmp.key: tmp = tmp.left else: tmp = tmp.right node.parent = parent if node.key < parent.key: parent.left = node else: parent.right = node return root O(h(T))

Usuwanie węzła - brak synów 5 12 1 6 14 13 17 20 16 10 19 15 5 12 1 6 14 13 17 20 16 10 19 Usuwany węzeł jest liściem – zastępujemy go przez None

Usuwanie węzła - jeden syn 5 12 1 6 14 13 17 20 16 10 19 15 5 1 6 14 13 17 20 16 10 19 15 Usuwany węzeł ma dokladnie jednego syna – usuwamy go „kompresując gałąź” w drzewie

Usuwanie węzła – dwóch synów x 16 17 10 19 10 19 12 5 17 20 12 5 20 18 1 6 18 11 1 6 11 Usuwany węzeł ma dwóch synów – usuwamy inny węzeł, który potrafimy (następnik(x) lub poprzednik(x) ) przepisujemy wartość z usuniętego węzła x

Usuwanie z drzewa BST O(h(T)) def BSTDeleteNode(root, node): ret = root if node.left==None or node.right==None: todel = node else: todel = BSTSuccesor(node) if todel.left!=None: son = todel.left else: son = todel.right if son!=None: son.parent = todel.parent if todel.parent == None: ret=son elif todel == todel.parent.left: todel.parent.left = son # todel is lson else: todel.parent.right = son # todel is rson if todel != node: node.key = todel.key node.data = todel.data return ret O(h(T))

Złożoność operacji BST Wszystkie kluczowe operacja na drzewach mają złożoność – odpowiadającą wysokości drzewa. Istotne jest utrzymanie jak namniejszej wysokości drzewa. W dowolnym węźle - poddrzewa: lewe i prawe - powinny mieć zbliżony rozmiar (drzewa zrównoważone) O(h(T))

Wzbogacanie struktury Wybór struktury podstawowej Określenie dodatkowych informacji Sprawdzenie czasu niezbędnego do aktualizacji dodatkowych informacji Zaprojektowanie nowych operacji

Drzewa statystyk pozycyjnych Dodatkowy element – rozmiar poddrzewa Zastosowania: Wyznaczanie statystyk pozycyjnych w czasie log(n) Wyznaczanie pozycji elementu w czasie log(n)

Drzewo statystyk pozycyjnych 21 20 26 15 12 40 7 17 41 47 2 10 7 25 4 18 4 14 21 30 47 5 4 11 2 16 2 20 1 23 1 27 2 10 16 19 23 28 38 4 2 46 1 7 7 1 12 17 1 20 29 1 39 12 1 3 1 def GetSize(node): if node==None: return 0 else: return node.size x.size = GetSize(x.left) + GetSize(x.right) +1

Drzewo przedziałowe W drzewie przechowywane są odcinki [a, b] Kluczem będzie lewy koniec odcinka tj. a Dodatkowy atrybut – max dla wszystkich prawych końców (tj. Max = Max(b)) w danym poddrzewie Aktualizacja max w czasie log(n) Zastosowania: Poszukiwanie przedziału zawierającego dany punkt Poszukiwanie przedziału mającego niepuste przecięcie z danym odcinkiem

Drzewo przedziałowe def Interval_search(root, a, b ): x = root while (x!=None && ([a,b]  [x.a, x.b] == )): if (x.left && x.left.max >= a): x = x.left else: x = x.right return x

Trie – od reTRIEval A B I F A B F I E U Y O R N N R S T T S N R S T E  E U Y O R N N R S T T S   N R S T E U Y O R  N S T D E E T Y R O S     D E  E T Y R O  S M M Kolejne sekwencje mogą być reprezentowane przez: wierzchołki krawędzie

Trie – KOMPRESJA WEZLOW SAMO SAMO S A L O C LOT CH A O L C H M T O H Ó O ODY ÓD M O T D O Ó D L O C Y D D O L C H Y T O H Ó O T O Ó D D Kompresja utrudnia modyfikację drzewa Y D D Y

Drzewo heterogeniczne TRIE A C NIEC HNĄĆ BST LIA RKA HAWKA HÓRZ MA