Foundations of Data Structures Practical Session #4 Recurrence ADT 08/04/2013Amihai Savir & Ilya Mirsky
Recurrence solution methods 2
The master method 3
Master method example 4
Example cont’d 5
6
ADT From Wikipedia: In computer science, an abstract data type (ADT) is a mathematical model for a certain class of data structures that have similar behavior. An abstract data type is defined indirectly, only by the operations that may be performed on it and by mathematical constraints on the effects (and possibly cost) of those operations. 7
Vector (Array) 8
Queue FIFO - First In First Out ADT that supports the following operations: enqueue(element) enqueue(element) – inserts new element at the tail of the queue. dequeue() dequeue() – removes and returns an element from the head of the queue. peek peek() – (optional) returns an element from the head of the queue, without removing it. isEmpty() isEmpty() – returns true if the queue is empty, 9
Stack LIFO - Last In First Out ADT that supports the following operations: push(element) push(element) – adds an element to the head of the stack. pop() pop() – removes and returns an element from the head of the stack. top() top() – (optional) returns the element from the head of the stack, without removing it. isEmpty isEmpty – returns true if the stack is empty. 10
Linked List A data structure that supports linear access to its elements. Each element points to the next element in the list. In a doubly-linked list: each element has 2 pointers, one to the next element in the list and the other to the previous element. 11
Question 1 Suggest 2 ways to implement a Queue using 2 Stacks. Solution Notice that the queue/stack is abstract, meaning the implementation isn't known, only the interface. In order to implement a queue we need to implement the following methods: enqueue(x), dequeue(), isEmpty() We will use stack A to hold the queue's elements and stack B as a temporary stack. We will use the Stack ADT operations: push(x), pop() and isEmpty(). 12
Question 1 cont’d enqueue (x) { moveElements(A, B) A.push(x) moveElements(B, A) } dequeue ( ) { element = A.pop() return element } isEmpty ( ) { return A.isEmpty() } moveElements(X, Y) { while (! X.isEmpty()){ temp = X.pop() Y.push(temp) } } 13 * In a very similar manner one can implement stack using 2 queues.
Question 1 cont’d Another solution enqueue (x) { moveElements(A, B) A.push(x) } dequeue ( ) { moveElements(B,A) element = A.pop() return element } isEmpty ( ) { return (A.isEmpty() && B.isEmpty()) } 14
Question 2* Suggest a way to implement a Stack using Linked List. Solution We will use an inner List L in order to hold the stack’s elements. 15
Question 2 cont’d pop() { element ← L.itemAt(0) L.removeItemAt(0) return element } push(x) { L.addToHead(x) } top() { element ← L.itemAt(0) return element } isEmpty() if L.size()=0 then return true else return false } 16
Question 3* 17 OperationTimeinit(n)O(n) isElement(k)O(1) insert(x, k) O(1) remove(k) isEmpty() hasAll () O(1)
Question 3 cont’d Insert (x, k) { A[k] = x count++ } remove (k) { A[k] = null count-- } isEmpty () { return (count == 0) } hasAll () { return (count == n) } 18
Question 4 19 OperationTime init(n)Initialize A with the value 1O(n 2 ) flip(i, j)Flip the value in A[i, j], i.e., A[i, j] = !A[i, j]O(1) hasRowOf1()Return true iff A has a row that contains only 1-sO(1) hasRowOf0()Return true iff A has a row that contains only 0-sO(1)
Question 4 cont’d flip(i,j) if (A[i][j] == 0) { if (Sum[i] == 0) count0- - Sum[i]++ if (Sum[i] == n) count1++ A[i][j] = 1 } else { if (Sum[i] == n) count1- - Sum[i]-- if (Sum[i] == 0) count0++ A[i][j] = 0 } 20
Question 5 21 OperationTime add(k, isSpecial) O(n) removeMin()O(1) removeMax() getOldest() Returns the oldest special number, according to insertion order O(1)
Question 5 cont’d 22