1 / 51

Algorithms and data structures

Algorithms and data structures. Recursive structures array , list, stack , queue. Array – random access structure. C/C++ const int MAX = 12; int Data [MAX] = {1,7,2,4,8,11,7,2}; Pseudokod Data = [1,7,2,4,8,11,7,2,0,0,0,0] # in fact in Python this is called list Data [ 5 ] = 5

lenoraj
Download Presentation

Algorithms and data structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Algorithmsand data structures Recursive structures array, list, stack, queue

  2. Array – random access structure C/C++ const int MAX = 12; int Data[MAX] = {1,7,2,4,8,11,7,2}; Pseudokod Data = [1,7,2,4,8,11,7,2,0,0,0,0] # in fact in Python this is called list Data[5] = 5 int i = 1 Data[i] = 5 Data[i+2] = 5 1 7 5 2 4 8 5 11 7 2 5

  3. Pseudocode again • Range in Python is a list and is indexed from 0 • Time of access is like for a list (i.e. o(n)) • Checking of lenght could be done with len function • Iterating for element in A : ..... • For defining ranges could be used range function range(1,10)returns range 1,2,3,4,5,6,7,8,9range(1,9,4) returns range 1, 5range(5,3) returns empty range range(5,3,-1) returns range 5, 4 So, the given codes are working in Python but given complexities are not valid because in Python [] denotes list

  4. Pseudocode again • Altough changes applied to parameters in Python are not transfered outside we will avoid sich constructions in pseudocode. • There is not necessary to free memory in Python and we will ommit this in pseudocode.

  5. Array – basic operations • Random access structure Operations • Writing - (1) : • A[i] = newValue • Reading - (1) : • value =A[i] • if value == A[i] • Searching through - O(n) or O(log n)depend on existence of elements order • for e in A : ... • for i in range(0,len(a)) : if A[i] == s : ... • element = find(A,pattern)

  6. Array – additional operations • Inserting - O(n) – n = number of moved elements for i in range(n-1, k, -1) : A[i+1] = A[i] A[k] = newElement • Changing the size - (n) : C/C++ : Resize(A, newSize) { tmp = alloc_the_new_array Copy_elements_from_A_to_the_temp free_A return tmp }

  7. Array of pointers xxx yyy zzz aaa bbb ccc ddd eee C/C++ ELEMENT Array[MAX]; ELEMENT *Array[MAX]; xxx yyy zzz aaa bbb NULL ccc NULL NULL ddd NULL eee In Python, .Net, Java objects (i.e. class instances) have pointer nature

  8. Swaping elements xxx xxx yyy yyy yyy zzz zzz zzz aaa bbb ccc aaa ddd eee bbb NULL ccc NULL NULL ddd NULL eee

  9. Warning Pointers have to point to something. We can allocate elements one by one or use an additional memory block/array 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[?]; !! Not used cells have to be NULL-ed

  10. Recurson of data C/C++ typedef int DATA; typedef struct SLNODE { DATA data; SLNODE *next; } *PSLNODE; SLNODE OneElement; C/C++ - another way typedefint DATA; structSLNODE; typedefSLNODE * PSLNODE; struct NODE { DATA data; PSLNODE next; } OneElement; Pseudokod : class SLNODE : data = None next = None

  11. Singly linked list data next data data next next data data next next cccccccc Root dddddddd AAAA bbbb xxxxxxxx

  12. Singly linked list class NODE : data = None next = None def PrintList(firstNode) :tmp = firstNodewhile tmp != None :print(tmp.data)tmp = tmp.next def GetListLen(firstNode) : cnt = 0tmp = firstNodewhile tmp != None : cnt = cnt+1 tmp = tmp.nextreturn cnt

  13. Singly linked list def GetFirst(firstNode) : if firstNode ==None :return None return firstNode def GetLast(firstNode) : if firstNode ==None :return None tmp = firstNode while tmp.next!=None : tmp = tmp.next return tmp Ussage : lastNode = GetLast(list)

  14. Singly linked list def AddFirst(firstNode, newNode) : newNode.next = firstNodereturn newNode def AddLast(firstNode, newNode) : newNode.next = None if firstNode == None :return newNode tmp = firstNodewhile tmp.next != None :tmp = tmp.nexttmp.next = newNodereturn firstNode Użycie : list = NonenewNode = Node()newNode.data = "abc" list = AddLast(list,newNode)

  15. Singly linked list def RemoveFirst(firstNode) :if firstNode == None : return Nonereturn firstNode.next def RemoveLast(firstNode) :if firstNode ==None :return None if firstNode.next==None : return None tmp = firstNodewhile tmp.next.next!=None : tmp = tmp.nexttmp.next = Nonereturn firstNode Ussage : list = RemoveFirst(list)

  16. Singly linked list – element removing data next data data next next data data next next cccccccc Root dddddddd AAAA bbbb xxxxxxxx

  17. Singly linked list – element inserting data next data data next next bbbb data data next next cccccccc Root dddddddd AAAA xxxxxxxx

  18. Singly linked list def FindNode(firstNode,dataPattern) : tmp = firstNodewhile tmp != None :if tmp.data == dataPattern : return tmp tmp = tmp.nextreturn None def GetAtPos(firstNode,pos) :#function returns element at position pos (0-based)#or None if not existstmp = firstNodewhile tmp != None : if pos == 0 : return tmp pos = pos – 1 tmp = tmp.nextreturn None

  19. Singly linked list def InsertAfter(newNode, node) : if node!= None : newNode.next = node.nextnode.next = newNode def RemoveAfter(node) : if node!= None : node.next = node.next.next #We skipped memory dealocation! #InsertBefore and RemoveNode – require #modification of previous node #So we have to find the previous node

  20. Singly linked list def InsertBefore(firstNode,newNode,dataPattern) : if firstNode ==None : return firstNodeif firstNode.data ==dataPattern :newNode.next = firstNode return newNodetmp = firstNodewhile tmp.next != None : if tmp.next.data == dataPattern : newNode.next = tmp.next tmp.next = newNode break tmp = tmp.next return firstNode

  21. Singly linked list def RemoveNode(firstNode,dataPattern) : if firstNode == None : return firstNodeif firstNode.data ==dataPattern :return firstNode.next tmp = firstNode while tmp.next != None : if tmp.next.data == dataPattern : tmp.next = tmp.next.next break tmp = tmp.next return firstNode

  22. Doubly linked list CCCCCCCC prev data next Aaaa prev data next XXXXXXXX prev data next BBBBBBB prev data next Root bbbb

  23. Doubly linked list class DLNODE :data = Nonenext = None prev = None We can use previous functions : PrintList(list) GetListLen(list) GetFirst(list) GetLast(list) GetAtPos(list, pos)

  24. Doubly linked list def AddFirst(firstNode, newNode) :newNode.prev = NonenewNode.next = firstNodeif firstNode != None : firstNode.prev = newNode return newNode def AddLast(firstNode, newNode) :last = GetLast(firstNode)newNode.prev = lastif last == None : return newNode last.next = newNode return firstNode Ussage : newNode = DLNODE() newNode.data = "ABC" list = AddLast(list,newNode)

  25. Doubly linked list -element removing CCCCCCCC prev data next Aaaa prev data next XXXXXXXX prev data next BBBBBBB prev data next Root bbbb

  26. Doubly linked list – element inserting CCCCCCCC prev data next Aaaa prev data next XXXXXXXX prev data next BBBBBBB prev data next Root bbbb

  27. Doubly linked list def InsertAfter(newNode, node) :if node==None : return newNode.next = node.nextnewNode.prev = nodeif node.next!=None :node.next.prev = newNode node.next = newNode def RemoveAfter(node) :if node==None : returnif node.next ==None : returnnode.next = node.next.next if node.next!=None :node.next.prev = node

  28. Doubly linked list def InsertBefore (firstNode, newNode, node) :if node==None : return firstNodenewNode.next = nodenewNode.prev = node.prevnode.prev = newNodeif newNode.prev==None : #very first node is added return newNode newNode.prev.next = newNodereturn firstNode Ussage : node = FindNode(list, whatToFind)list = InsertBefore(list, newNode, node)

  29. Doubly linked list def RemoveNode(firstNode, node) :if node==None : return firstNodeif node.next!= None : node.next.prev = node.previf node.prev == None : #i.e. firstNode==node return node.nextnode.prev.next = node.nextreturn firstNode Użycie : node = FindNode(list, whatToFind)list = RemoveNode(list, node)

  30. Doubly linked list def RemoveFirst(firstNode) : return RemoveNode(firstNode, firstNode) def RemoveLast(firstNode) :last = GetLast(firstNode) return RemoveNode(firstNode, last) Ussage : list = RemoveFirst(list)

  31. List – sequential access structure Operations : • Searching through - O(n) • Inserting ath the beggining - (1) • Removing the first element - (1) • Inserting to i-th pos - O(i) : GetAt+InsertAfter • Read - O(n) : GetAt(list,i-1) • Inserting at the end (n) ?? • Removing the last element (n) ??

  32. Stack - Last In First Out Example of application: DFS zzz zzz ttt Pop zzz ttt xxx Push yyy zzz aaa bbb ccc ddd eee

  33. Queue - First In First Out zzz ttt eee Example of application: BFS Put zzz ttt xxx yyy zzz aaa bbb ccc ddd Get eee

  34. Stack implemented with array aaa aaa bbb bbb bbb 1 2 1 cnt=0 def Push(element) : if cnt < MAXarray[cnt] = elementcnt= cnt+1else : ERROR("overflow") def Pop() if cnt <=0 :ERROR("stack is empty")else : cnt = cnt-1 return array[cnt] array[MAX]; 0 cnt Problem : limited capacity

  35. Queue implemented with array aaa aaa aaa bbb bbb 1 2 1 1 ELEMENT array[MAX]; Problem : • limited capacity • migration of elements Implementation • Moving elements when end of buffer is reached • Tracing the begining and the end of elements (complex) – cyclic buffer 0 long Cnt 0 long First

  36. Stack/queue implemented with list • Push -> AddFirst() => (1) • Put -> AddLast() => (n) or O(1) • Pop/Get -> GetFirst() + RemoveFirst() => (1) Push, Put alocate the new node (i.e. they got the data as a parameter) def Push(stack, dataToStore) : node = SLNODE() node.data = dataToStore return AddFirst(stack, node) def Put(queue, dataToStore) : node = DLNODE() node.data = dataToStore return AddLast(queue, node)

  37. Stack/queue implemented with list Get, Pop return data (not node) (and deallocation was skipped) def Pop(stack) : ret = GetFirst(stack) if ret==None : ERROR("Stack is empty") return RemoveFirst(stack), ret.data def Get(queue) : ret = GetFirst(queue) if ret==None : ERROR("Queue is empty")return RemoveFirst(queue), ret.data Ussage: stack,value = Pop(stack)

  38. Queue implemented with list O(1) def Put(firstNode, lastNode, dataToStore) :node = DLNODE()node.data = dataToStorenode.next = None node.prev = lastNodeif lastNode ==None :# queue is emptyreturn node, node lastNode.next = nodereturn firstNode, node Ussage : start,end = Put(start,end,"abc")

  39. Queue implemented with list O(1) def Get(firstNode, lastNode) : if firstNode===None : ERROR("Kolejka jest pusta")elif firstNode == lastNode : return None, None, firstNode.dataif (firstNode.next == None) : return None, None, firstNode.data ret = firstNode.data return RemoveFirst(firstNode), lastNode, ret Ussage : start,end,value = Get(start,end)

  40. Cyclic list (singly linked) Root Aaaa data next pWrite CCCCCCCC data next XXXXXXXX bbbb data next pRead BBBBBBB data next

  41. Cyclic list (doubly linked) Aaaa prev data next CCCCCCCC prev data next XXXXXXXX prev data next BBBBBBB prev data next Root pWrite bbbb pRead

  42. Cyclic list • The last element points to the first one • In case of doubly linked list – also the first element points to the last one • Insert, remove are similar to non-cyclic list • Searching: it is necessary to remember the begining to know when finish the search • Joning of two lists – what time?

  43. Pointer structures – without pointers xxx yyy zzz aaa bbb ccc ddd eee int arrOfPtrs[MAXPTR]; ELEMENT elements[MAXEL]; 0 1 3 -1 -1 -1 -1 -1 int ptr; 3

  44. Stack application - example • Locations visiting – DFS def VisitRooms(startRoom) :stack = []stack = Push(stack, startRoom)while stack != None :stack,current = Pop(stack)neighbours = get_neighbours(current) for room in neighbours : if not already_visited(room) :mark_visited(room) stack = Push (stack, room) • Locations visiting - BFS : Push -> PutPop -> Get

  45. Reverse Polish Notation • Base on notation proposed by Jan Łukasiewicz • It allows to express and perform calculation without parenthesis, priorities etc. • a+b*c ONP: a b c * + • a+b*c-7 ONP: a b c * + 7 - • b*c-(d+e)*4 ONP: b c * d e + 4 * - ONP is ambigious i.e. single expression can be represented in more than one (legal) way

  46. ONP - calculation Calculation : • Process all the ONP tokens • If token is operand push to the stack • If token is operator • Pull from the stack proper number of elements • Do calculations • Push the result to the stack • The top of stack is a Result

  47. ONP - calculation def ONPCalc(onp) : ’’’Function returns the result of ONP expression evaluation. Example : 3 4 * 2 +’’’stack = None while onp != None :onp,token = get_next_token(onp) if is_operand(token) : stack = Push(stack, token) else : stack, op1 = Pop(stack) stack, op2 = Pop(stack) result = do_calculation(token,op1,op2) stack = Push(stack, result)stack,result = Pop(stack)return result

  48. Example of ONP calculations

  49. Conversion to ONP Conversion : Get next expression token If token is operand write token to output If token is operator "(" push it stack If token is operator ")" pull from stack all the operators until "(" including this one If token is other operator pull from stack all operators with higher or equal (not less important) priorities and write to outputpush token to stack When all the elements are processed write all stack (one by one) to output

  50. ONP - conversion def ONPConv(expression) :stack = Noneonp = Nonewhile expression != None :expression, token = get_next_token(expression) if is_operand(token):onp = Put(onp, token) elif token == "(" : stack = Push(stack, token) elif token == ")" : while stack != None : stack,token = Pop(stack) if token =="(" : break else : onp = Put(onp,token) else :priority = get_priority(token) while stack != None :stack,top = Pop(stack) if top=="(" or get_priority(top)<priority : stack = Push(stack,top)break onp = Put(onp, top)stack = Push(stack,token) while stack != None : stack, item = Pop(stack) onp = Put(onp, item)return onp

More Related