Algorytmy i struktury danych

Slides:



Advertisements
Podobne prezentacje
PRAM.
Advertisements

Analiza wywołania i przebiegu przerwań w systemie Linux
Wskaźniki repetytorium Wskaźniki int Y = 1, X = 2; X = 5; int *p = &X; Y X p 4 4 p = &Y; *p = 4; 5.
Zaawansowane techniki algorytmiczne
Dynamiczne struktury danych Listy, Kolejki, Stosy
ALLEGRO PIERWSZA GRA: WYŚCIG
C++ w Objectivity Marcin Michalak s1744. Pomocne pakiety: Data Definition Language (DDL). Standard Template Library (STL). Active Schema.
Java vs C# Michał Prządka Tomasz Nowak
STL - Standard Template Library Autor: Błażej Chodarcewicz rainbow.mimuw.edu.pl/~bc189380/STL/
OOPC++ - operatory1 Operatory class complex { private: double re, im; public: complex (double r, double i = 0) { re = r; im = i; } friend complex operator+
Testowanie oprogramowania metodą badania pokrycia kodu
Łukasz Monkiewicz.
Współprogramy Plan: Motywacja Składnia Scenariusz obiektu współprogramu Przykłady Producent – konsument ( instrukcja attach ) Czytelnik -pisarze ( instukcja.
142 JAVA – sterowanie i wątki public class A20 extends javax.swing.JApplet implements ActionListener { private int licznik = 0; private JTextField t =
Podstawy programowania II
REKURENCJA.
Algorytmy i struktury danych
Krzysztof Manuszewski
Programowanie obiektowe III rok EiT
Złożone typy danych Listy Tworzenie elastycznych baz danych
Czyli jak zrobić prezentację komputerową?
Co można zwiedzić w WIELKIEJ BRYTANII Pamiętajmy o miejscach które możemy zwiedzić na przykład w WIELKIEJ BRYTANII. I też czym różni się ta wyspa od naszego.
Małgorzata Pietroczuk
Ułamki dziesiętne.
funkcja przyjmuje wartości dodatnie, a dla jakich ujemne?
FUNKCJA L I N I O W A Autorzy: Jolanta Kaczka Magdalena Wierdak
Informatyka Edytor tekstów Word.
III. Proste zagadnienia kwantowe
Elektronika cyfrowa Prezentacja Remka Kondrackiego.
Tworzenie tabel na stronach internetowych Program NVU Spis prezentacji: 1.Wstawianie tabeliWstawianie tabeli 2.ZakładkiZakładki.
To jest bardzo proste  Lekcja nr 3
Tablice.
Przeglądanie inOrder function BSTinorder(BSTNode root) if root NOT NULL BSTinorder(root.left) Print(root) BSTinorder(root.right) 2, 4, 6, 8, 9, 10, 12,
Prezentacja z przedmiotu „systemy wizyjne”
Podstawy programowania
SZABLONY STOSOWANIE SZABLONÓW PODZIEL I ZMIERZ. Określanie miary i podziału Czasami konieczne jest zaznaczenie punktów na obiekcie położonych w równych.
Formatowanie i modyfikacja dokumentu tekstowego
ASD Algorytmy sortujące
KLAWIATURA Co to jest?.
TYPY STRUKTURALNE Tablice Tablicą nazywamy złożoną strukturę danych, która zawiera zbiór elementów tego samego typu.
ALGORYTMY.
ALGORYTM.
1.
Wykonała Sylwia Kozber
Powrót do sukcesu Analiza przypadku Princessy (rola badań marketingowych podczas rozwoju produktu: ) Powrót do sukcesu Analiza przypadku Princessy.
xHTML jako rozszerzenie HTML
Instalacja serwera WWW na komputerze lokalnym
PHP Operacje na datach Damian Urbańczyk. Operacje na datach? Dzięki odpowiednim funkcjom PHP, możemy dokonywać operacji na datach. Funkcje date() i time()
HTML Podstawy języka hipertekstowego Damian Urbańczyk.
Tworzenie tabel w edytorze Word
Warsztaty C# Część 2 Grzegorz Piotrowski Grupa.NET PO
Warsztaty C# Część 3 Grzegorz Piotrowski Grupa.NET PO
TWORZENIE SPISU TREŚCI Opracowała: Iwona Kowalik.
SKALA MAPY Skala – stosunek odległości na mapie do odpowiadającej jej odległości w terenie. Skala najczęściej wyrażona jest w postaci ułamka 1:S, np. 1:10.
1 Strategia dziel i zwyciężaj Wiele ważnych algorytmów ma strukturą rekurencyjną. W celu rozwiązania rozwiązania problemu algorytm wywołuje sam siebie.
A. Jędryczkowski – 2006 ©. Tablica to struktura danych zawierająca zbiór obiektów tego samego typu i odpowiada matematycznemu pojęciu wektora (tablica.
Pliki elementowe – A. Jędryczkowski © 2007 Turbo Pascal umożliwia wykorzystanie w programach plików elementowych. Pliki takie zawierają informację zakodowaną
Łamana Anna Gadomska S.P. 79 Łódź.
Zmiany w Przepisach Gry w Piłkę Nożną od 1 września 2006r. Kolegium Sędziów Warmińsko-Mazurskiego Związku Piłki Nożnej.
Temat 5: Elementy meta.
Instrukcja switch switch (wyrażenie) { case wart_1 : { instr_1; break; } case wart_2 : { instr_2; break; } … case wart_n : { instr_n; break; } default.
Instrukcja switch switch (wyrażenie) { case wart_1 : { instr_1; break; } case wart_2 : { instr_2; break; } … case wart_n : { instr_n; break; } default.
Instrukcje sterujące: W instrukcjach sterujących podejmowane są decyzje o wykonaniu tych czy innych instrukcji programu. Decyzje te podejmowane są w zależności.
Komtech Sp. z o.o. Magic Janusz ROŻEJ.
w/g Grzegorz Gadomskiego
1 Technika cyfrowa Systemy zapisu liczb wykonał Andrzej Poczopko.
Silverlight 4 dla Windows Phone 7
1.
Algorytmy i Struktury Danych Struktury Danych
ALGORYTMY I STRUKTURY DANYCH
Zapis prezentacji:

Algorytmy i struktury danych struktury rekurencyjne tablice, listy, stosy, kolejki 1

Tablica – struktura o swobodnym dostępie C/C++ const int MAX = 12; int i, Data[MAX] = {1,7,2,4,8,11,7,2}; Pseudokod Data = [1,7,2,4,8,11,7,2,0,0,0,0] # de facto w Pythonie nazywa się to lista i = 1 Data[i] = 5 Data[5] = 5 Data[i+2] = 5 1 7 5 2 4 8 5 11 7 2 5

Jeszcze o pseudokodzie tablica (lista w Pythonie) indeksowane są od 0 sprawdzanie długości możliwe jest funkcją len tablice można konkatenować t1 = t2+t3 iterowanie for element in A : ..... do definiowania zakresów służy funkcja range range(1,10) zwraca zakres 1,2,3,4,5,6,7,8,9 range(1,9,4)zwraca zakres 1, 5 range(5,3)zwraca zakres [] range(5,3,-1)zwraca zakres [5, 4] dopuszczalne jest konkatenowanie zakresów np [1,2,3] + [5,7]

Tablica – podstawowe operacje Struktura o dostępie swobodnym Operacje Zapis - (1) : A[i] = newValue Odczyt - (1): value = A[i] if value == A[i] Przeszukiwanie - O(n) lub O(log n) w zależności od uporządkowania for e in A : ... for i in range(0,len(a)): if A[i] == s: ... element = find(A,pattern)

Tablica – dodatkowe operacje Wstawianie - O(n) – n = liczba elementów przed for i in range(n-1, k, -1) : A[i+1] = A[i] A[k] = newElement Zmiana rozmiaru - (n): C/C++: Resize(A, newSize) { tmp = alokuj_nowa_tablice kopiuj_elementy_z_A_do_nowej_tablicy zwolnij_A return tmp }

Tablica wskaźników xxx xxx yyy yyy zzz zzz aaa bbb ccc aaa ddd eee bbb C/C++ ELEMENT Array[MAX]; ELEMENT *Array[MAX]; xxx xxx yyy zzz aaa bbb ccc ddd eee yyy zzz aaa bbb NULL ccc NULL NULL NULL ddd eee W jęz. Python, .Net, Java obiekty klas mają charakter wkaźników

Zamiana elementów xxx xxx yyy yyy yyy zzz zzz zzz aaa bbb ccc aaa ddd eee bbb NULL ccc NULL NULL NULL ddd eee !! Uwaga należy wyzerować nieużywane komórki

UWAGA Musimy mieć na co pokazywać, można alokować pojedyncze elementy lub skorzystać z dodatkowej tablicy xxx ELEMENT Array[...]; C/C++: Element *Array[MAX]; for (i.... ) A[i] = new Element; yyy zzz aaa for (....) Array[i] = &tab[j]; bbb ccc NULL ddd NULL eee NULL NULL ELEMENT tab[?];

Rekurencja danych Pseudokod: class SLNODE : C/C++ C/C++ - inaczej typedef int DATA; typedef struct SLNODE { DATA data; SLNODE *next; } *PSLNODE; SLNODE OneElement; C/C++ - inaczej typedef int DATA; struct SLNODE; typedef SLNODE * PSLNODE; struct NODE { DATA data; PSLNODE next; } OneElement; Pseudokod: class SLNODE : data = None next = None

Lista jednostronnie wiązana data next cccccccc Root data next AAAA data next dddddddd data next bbbb data next xxxxxxxx

Lista jednostronnie wiązana class NODE : data = None next = None def PrintList (list): tmp = list while tmp != None: print tmp.data tmp = tmp.next def ListLen(list): cnt = 0 tmp = list while tmp != None : cnt = cnt+1 tmp = tmp.next return cnt

Lista jednostronnie wiązana def AddHead(list, newNode): newNode.next = list return newNode def AddTail(list, newNode): newNode.next = None if list == None : return newNode else : tmp = list while tmp.next != None : tmp = tmp.next tmp.next = node return list Użycie: newNode = Node() newNode.data = "abc" list = AddTail(list,newNode)

Lista jednostronnie wiązana def GetHead (list): if list==None : return None else : return list def GetTail(list): if list==None : return None else: tmp = list while tmp.next!=None: tmp = tmp.next return tmp Użycie: lastNode = GetEnd(list)

Lista jednostronnie wiązana def RemoveHead(list): if list== None : return None else : return list.next def RemoveTail(list): if list==None : return None elif list.next==None : return None else: tmp = list while tmp.next.next!=None: tmp = tmp.next tmp.next = None return list Użycie: list = RemoveHead(list)

Lista jednostronnie wiązana- usuwanie elementu data next cccccccc Root data next AAAA data next dddddddd data next bbbb data next xxxxxxxx

Lista jednostronnie wiązana- dodawanie elementu data next cccccccc Root data next AAAA data next dddddddd data next bbbb data next xxxxxxxx

Lista jednostronnie wiązana def FindNode(lista,dataPattern): tmp = list while tmp != None: if tmp.data == dataPattern : return tmp return None def GetAt(lista,pos): #funkcja zwraca element na pozycji pos liczac od 0 #jesli nie ma tyulu elementow zwraca None tmp = list while tmp != None: if pos == 0 : return tmp pos = pos - 1 return None

Lista jednostronnie wiązana def InsertAfter(node, newNode): newNode.next = node.next node.next = newNode def DeleteAfter(node): node.next = node.next.next #InsertBefore i DeleteNode – wymagaja #modyfikacji wezla wczesniejszego

Lista jednostronnie wiązana def InsertBeforeNode(lista,newNode,dataPattern): if list==None : return list elif list.next==None : if list.data!=dataPattern: return list else: newNode.next = list return newNode else: tmp = list while tmp.next != None: if tmp.next.data == datPattern : newNode = tmp.next tmp.next = newNode break return list

Lista jednostronnie wiązana def DeleteNode(list,dataPattern): if list== None : return list elif list.next== None : if list.data!=dataPattern: return list else: return list.next else: tmp = list while tmp.next != None : if tmp.next.data == datPattern : tmp.next = tmp.next.next break return list

Lista dwustronnie wiązana data next CCCCCCCC prev Root data next Aaaa prev data next XXXXXXXX prev bbbb data next BBBBBBB prev

Lista dwustronnie wiązana class DLNODE : data = None next = None prev = None Identyczne będą funkcje: PrintList(list) ListLen(list) GetHead(list) GetTail(list) FindNode(list,dataPattern)

Lista dwustronnie wiązana def AddHead(list, newNode): newNode.prev = None newNode.next = list if list!= None : list.prev = newNode return newNode def AddTail(list, newNode): tail = GetTail(list) newNode.prev = tail if tail== None : return newNode tail.next = newNode return tail Użycie: newNode = DLNODE() newNode.data = "ABC" list = AddTail(list,newNode)

Lista dwustronnie wiązana usuwanie elementu data next CCCCCCCC prev Root data next Aaaa prev data next XXXXXXXX prev bbbb data next BBBBBBB prev

Lista dwustronnie wiązana wstawianie elementu data next CCCCCCCC prev Root data next Aaaa prev data next XXXXXXXX prev bbbb data next BBBBBBB prev

Lista dwustronnie wiązana def InsertAfter(node, newNode): if node==None: return newNode.next = node.next newNode.prev = node if node.next!=None : node.next.prev = newNode node.next = newNode

Lista dwustronnie wiązana def InsertBeforeNode (list, node, newNode): if node==None : return list newNode.next = node newNode.prev = node.prev node.pev = newNode if newNode.prev==None : # i.e. list = node return newNode newNode.prev.next = newNode return list Użycie: node = FindNode(list, whatToFind) list = InsertBefore(list, node, newNode)

Lista dwustronnie wiązana def DeleteAfter(node): node.next = node.next.next if node.next != None : node.next.prev = node def DeleteNode(list, node): tmp = node.next if node.next!= None : node.next.prev = node .prev if node.prev == None : #i.e. list == node return node.next node.prev.next = node.next return list Użycie: node = FindNode(list, whatToFind) DeleteAfter(node) list = DeleteBefore(list, node)

Lista dwustronnie wiązana def InsertAfter(node, newNode): newNode.next = node.next newNode.prev = node if node.next!= None : node.next.prev = newNode node.next = newNode def DeleteAfter(node): node.next = node.next.next if node.next != None : node.next.prev = node

Lista - struktura o dostępie sekwencyjnym Operacje: Przeszukiwanie - O(n) (zależy ? od uporządkowania) Wstawianie na poczatek - (1) Usuwanie z poczatku - (1) Zapis na i-ta pozycję - O(n) : GetAt+InsertAfter Odczyt - O(n): GetAt(list,i-1) Wstawianie na koniec (n) ?? Usuwanie z końca (n) ??

Stos - Last In First Out Przykład zastosowania np. DFS zzz zzz ttt Pop xxx Push yyy zzz aaa bbb ccc ddd eee

Kolejka - First In First Out zzz Przykład zastosowania np. BFS ttt Put zzz ttt xxx yyy zzz aaa bbb ccc ddd Get eee eee

Tablicowa realizacja stosu Cnt=0 def Push(Element): if Cnt<MAX Array[Cnt] = Element Cnt=Cnt+1 else: ERROR"przepelnienie" def Pop() if Cnt<=0: ERROR"stos pusty" else: cnt = cnt-1 return Array[cnt] } Array[MAX]; aaa 1 aaa bbb bbb 1 bbb 2 Cnt Problem:Ograniczona pojemność stosu

Tablicowa realizacja kolejki ELEMENT Array[MAX]; Problem: ograniczona pojemność stosu wędrujące elementy Realizacja realokacji elementów po osiągnięciu końca buforu śledzenie początku i końca (skomplikowane) – tzw. bufor cykliczny aaa 1 aaa 1 aaa bbb bbb 2 long Cnt long First

Listowa realizacja stosu/kolejki PUSH/PUT -> AddHead() = (1) POP -> GetHead() + DeleteHead() = (1) GET -> GetTail() + DeleteTail() = O(n) def Push(stack, data): node = NODE() node.data = data return AddHead(stack, data)

Listowa realizacja kolejki/stosu def Pop(stack): ret = GetHead(stack) if ret==None: ERROR "Stos jest pusty" else: return (DeleteHead(stack), ret.data) def Get(stack): ret = GetTail(stack) if ret==None : ERROR "Stos jest pusty" else: return (DeleteTail(stack), ret.data) Użycie: stack,value = pop(stack)

Listowa realizacja kolejki w czasie stałym def Put(startList, endList, dataNode): node = DLNODE() node.data = dataNode if startList==None : node.next = None node.prev = None return (node, node) else: node.prev = None node.next = startList startList.prev = node return (node, endList) Użycie: start,end = Put(start,end,"abc")

Listowa realizacja kolejki w czasie stałym def Get(startList, endList): if startList==None : ERROR "Lista jest pusta" elif startList==endList: return (None, None, startList.data) else: ret = endList newEnd = endList.prev newEnd.next = None return (startList, newEnd, ret.data) Użycie: start,end,value = Get(start,end)

Lista cykliczna (jednostronna) Root Aaaa data next pWrite CCCCCCCC data next XXXXXXXX bbbb data next pRead BBBBBBB data next

Lista cykliczna (dwustronna) Root data next Aaaa prev pWrite data next CCCCCCCC prev data next XXXXXXXX prev bbbb pRead data next BBBBBBB prev

Lista cykliczna Ostatni element pokazuje na pierwszy W przypadku cyklicznej l. dwukierunkowej – również pierwszy na ostatni Wstaw, usuń analogicznie do listy zwykłej Szukanie – należy zapamiętać początek poszukiwań aby wiedzieć kiedy je zakończyć

Struktury wskaźnikowe bez wskaźników int arrOfPtrs[MAXPTR]; ELEMENT elements[MAXEL]; xxx yyy zzz aaa bbb ccc ddd eee 1 3 -1 -1 -1 -1 -1 int ptr; 3

Przykład użycia stosu odwiedzanie pomieszczen – DFS def VisitRooms(start): stack = None stack = Push(stack, start) while (stack!= None) : stack,current = Pop(stack) neighbours = GetNeighbourhood(current) for room in neighbours : if not Already_Visited(room): stack = Push (stack, room) odwiedzanie pomieszczen BFS: Push -> Put Pop -> Get

Odwrotna Notacja Polska Rozwinięcie notacji zaproponowanej przez Jana Łukasiewicza Pozwala wykonywać obliczenia bez nawiasów, bez potrzeby stosowania prorytetów a+b*c przedstawiane jest jako a b c * + a+b*c-7 przedstawiane jest jako a b c * + 7 - b*c-(d+e)*4 przedstawiane jest jako b c * d e + 4 * -

ONP - obliczenia def ONPCalc(onp): "Funkcja oblicza wyniki wyrazenia w ONP Obslugiwane są operatory 2 argumentowe. Przyklad 3 4 * 2 +" stack = None while onp!= None : item = DajKolejnyElementWyrażenia(onp) if JestOperandem(item): stack = Push(stack,item) else: stack, op1 = Pop(stack) stack, op2 = Pop(stack) result = WykonajObliczenia(op, arg1, arg2) stack = push(stack, result) stack,result = Pop(stack) return result

ONP - obliczenia Obliczenia: weź element wyrażenia jeżeli to operand połóż go na stosie jezeli to operator zdejmij ze stosu odpowiednią liczbę operandów, wykonaj obliczenia i odłóż wynik na stos wynik znajduje sie na górze stosu

ONP – przykład obliczeń Wejście Bieżący Stos po b. operacji 2, 3, *, 5, +, 7, * 3, *, 5, +, 7, * 2 *, 5, +, 7, * 3 2,3 5, +, 7, * * 6 +, 7, * 5 6, 5 7, * + 11 7 11, 7 77

ONP - konwersja Konwersja: Pobierz kolejny element wyrazenia Jesli jest to operand przepisz na wyjście Jeśli jest to operator ")" zdejmij se stosu wszystkie operatory aż do nawiasu otwierającego Jeśli jest to operator "(" połóż go na stosie Jeśli to inny niż nawiasy zdejmij se stosu wszystkie operatory o priorytecie wyższym lub równym do bieżącego i połóż bieżacy operator na stosie Po przetworzeniu wyrażenia przepisz stos na wyjście

def ONPConv(expression): stack = None onp = None while expression def ONPConv(expression): stack = None onp = None while expression!= None : item = DajKolejnyElementWyrażenia(expression) if JestOperandem(item) : onp = onp + [item] elif item == "(" : stack = push(stack,item) elif item == ")" : while (stack!= None): stack,item = Pop(stack) if item=="(": break else : onp = onp + [item] else: priority = DajPriorytet(item) while (stack!= None): top = GetHead(stack).data if top=="(": break if DajPriorytet(top)>priority: break result = Put result + [top] stack = RemoveHead(stack) stack = Push(stack,item) while stack!= None : stack, item = Pop(stack) onp = onp + [item] return onp ONP - konwersja

ONP – przykład konwersji Wejście Wyjście Stos b*c-(d+e)*4 *c-(d+e)*4 b c-(d+e)*4 * -(d+e)*4 b c (d+e)*4 b c * - d+e)*4 - ( +e)*4 b c * d )*4 - ( + * 4 b c * d e 4 b c * d e + - * b c * d e + 4 b c * d e + 4 * b c * d e + 4 * -