Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

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

Podobne prezentacje


Prezentacja na temat: "Algorytmy i struktury danych struktury rekurencyjne tablice, listy, stosy, kolejki."— Zapis prezentacji:

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

2 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] =

3 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]

4 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)

5 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 }

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

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

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

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

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

11 Lista jednostronnie wiązana 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 class NODE : data = None next = None

12 Lista jednostronnie wiązana 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) def AddHead(list, newNode): newNode.next = list return newNode

13 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)

14 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)

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

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

17 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

18 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

19 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

20 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

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

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

23 Lista dwustronnie wiązana 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) def AddHead(list, newNode): newNode.prev = None newNode.next = list if list!= None : list.prev = newNode return newNode

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

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

26 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

27 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)

28 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)

29 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

30 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) ??

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

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

33 Tablicowa realizacja stosu Cnt=0 def Push(Element): if Cnt

34 Tablicowa realizacja kolejki 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 ELEMENT Array[MAX]; 0 long Cnt aaa bbb aaa 1 bbb 2 long First 0 aaa 1 1

35 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)

36 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)

37 Listowa realizacja kolejki w czasie stałym Użycie: start,end = Put(start,end,"abc") 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)

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

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

41 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ć

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

43 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

44 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 * b*c-(d+e)*4 przedstawiane jest jako b c * d e + 4 * -

45 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

46 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

47 ONP – przykład obliczeń WejścieBieżącyStos po b. operacji 2, 3, *, 5, +, 7, * 3, *, 5, +, 7, *22 *, 5, +, 7, *32,3 5, +, 7, **6 +, 7, *56, 5 7, *+11 *711, 7 *77

48 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

49 ONP - konwersja 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

50 ONP – przykład konwersji WejścieWyjścieStos b*c-(d+e)*4 *c-(d+e)*4b c-(d+e)*4b* -(d+e)*4b c* (d+e)*4b c *- d+e)*4b c *- ( +e)*4b c * d- ( )*4b c * d- ( + * 4b c * d e- ( + 4b c * d e +- * b c * d e + 4- * b c * d e + 4 *- b c * d e + 4 * -


Pobierz ppt "Algorytmy i struktury danych struktury rekurencyjne tablice, listy, stosy, kolejki."

Podobne prezentacje


Reklamy Google