1 Abstract Data Types Stack, Queue Amortized analysis Cormen: Ch 10, 17 (11, 18)

Slides:



Advertisements
Similar presentations
§3 The Stack ADT 1. ADT A stack is a Last-In-First-Out (LIFO) list, that is, an ordered list in which insertions and deletions are.
Advertisements

1 Persistent data structures. 2 Ephemeral: A modification destroys the version which we modify. Persistent: Modifications are nondestructive. Each modification.
Data Structures and Algorithms (60-254)
Data Structures Haim Kaplan and Uri Zwick October 2013 Lecture 2 Amortized Analysis “amortized analysis bounds the worst case running time of a sequence.
Queue & List Data Structures & Algorithm Abstract Data Types (ADTs) ADT is a mathematically specified entity that defines a set of its instances,
Stacks, Queues, and Deques. 2 A stack is a last in, first out (LIFO) data structure Items are removed from a stack in the reverse order from the way they.
ADT Stacks and Queues. Stack: Logical Level “An ordered group of homogeneous items or elements in which items are added and removed from only one end.”
 Abstract Data Type Abstract Data Type  What is the difference? What is the difference?  Stacks Stacks  Stack operations Stack operations  Parsing.
 Balancing Symbols 3. Applications
CSE332: Data Abstractions Lecture 21: Amortized Analysis Dan Grossman Spring 2010.
Data Structures Haim Kaplan and Uri Zwick February 2010 Lecture 2 Amortized Analysis “amortized analysis finds the average running time per operation over.
CPSC 411, Fall 2008: Set 6 1 CPSC 411 Design and Analysis of Algorithms Set 6: Amortized Analysis Prof. Jennifer Welch Fall 2008.
Tirgul 9 Amortized analysis Graph representation.
UMass Lowell Computer Science Graduate Analysis of Algorithms Prof. Karen Daniels Spring, 2009 Lecture 3 Tuesday, 2/10/09 Amortized Analysis.
Stacks, Queues & Deques CSC212.
CS 206 Introduction to Computer Science II 10 / 15 / 2008 Instructor: Michael Eckmann.
The Potential Method. Deque with stacks size=7 13 S1S1 S2S2 push(x,D): push(x,S 1 ) push(2,D)
TCSS 342, Winter 2005 Lecture Notes
Stacks, Queues, and Deques
1 Abstract Data Types Queue + Dequeue Amortized analysis.
Stacks, Queues, and Deques. A stack is a last in, first out (LIFO) data structure –Items are removed from a stack in the reverse order from the way they.
Stacks, Queues, and Deques
CSE332: Data Abstractions Lecture 26: Amortized Analysis Tyler Robison Summer
Objectives of these slides:
Comp 249 Programming Methodology Chapter 15 Linked Data Structure - Part B Dr. Aiman Hanna Department of Computer Science & Software Engineering Concordia.
Chapter 7 Stack. Overview ● The stack data structure uses an underlying linear storage organization.  The stack is one of the most ubiquitous data structures.
Comp 245 Data Structures Stacks. What is a Stack? A LIFO (last in, first out) structure Access (storage or retrieval) may only take place at the TOP NO.
Implementing Stacks Ellen Walker CPSC 201 Data Structures Hiram College.
Stack and Queue.
Week7 Stack Data Structures & Algorithms. Introduction to Stacks and Queues Widely used data structures Ordered List of element Easy to implement Easy.
CHAPTER 05 Compiled by: Dr. Mohammad Omar Alhawarat Stacks & Queues.
October 18, Algorithms and Data Structures Lecture V Simonas Šaltenis Nykredit Center for Database Research Aalborg University
Stacks and Linked Lists. Abstract Data Types (ADTs) An ADT is an abstraction of a data structure that specifies – Data stored – Operations on the data.
Adapted from instructor resources Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 223 – Advanced Data Structures Course Review Midterm.
Analysis of Algorithms
Amortized Analysis Typically, most data structures provide absolute guarantees on the worst case time for performing a single operation. We will study.
Algorithm Analysis (Algorithm Complexity). Correctness is Not Enough It isn’t sufficient that our algorithms perform the required tasks. We want them.
30 May Stacks (5.1) CSE 2011 Winter Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data structure An.
IKI 10100: Data Structures & Algorithms Ruli Manurung (acknowledgments to Denny & Ade Azurat) 1 Fasilkom UI Ruli Manurung (Fasilkom UI)IKI10100: Lecture6.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 18: Stacks and Queues (part 2)
1 Linked-list, stack and queue. 2 Outline Abstract Data Type (ADT)‏ Linked list Stack Queue.
Advanced Algorithm Design and Analysis (Lecture 12) SW5 fall 2004 Simonas Šaltenis E1-215b
David Luebke 1 12/12/2015 CS 332: Algorithms Amortized Analysis.
Week 5 - Wednesday.  What did we talk about last time?  Recursion  Definitions: base case, recursive case  Recursive methods in Java.
Copyright © Curt Hill Stacks An Useful Abstract Data Type.
Parasol Lab, Dept. CSE, Texas A&M University
2005MEE Software Engineering Lecture 7 –Stacks, Queues.
Stacks A stack is a linear data structure that can be accessed only at one of its ends for storing and retrieving data LIFO (Last In First Out) structure.
CSE373: Data Structures & Algorithms Lecture 8: Amortized Analysis Dan Grossman Fall 2013.
CH 5 : STACKS, QUEUES, AND DEQUES ACKNOWLEDGEMENT: THE SLIDES ARE PREPARED FROM SLIDES PROVIDED WITH DATA STRUCTURES AND ALGORITHMS IN C++, GOODRICH, TAMASSIA.
Lecture 10 b Stacks b Queues. 2 Stacks b A stack ADT is linear b Items are added and removed from only one end of a stack b It is therefore LIFO: Last-In,
Data Structures and Algorithm Analysis Dr. Ken Cosh Linked Lists.
Chapter 3 Lists, Stacks, Queues. Abstract Data Types A set of items – Just items, not data types, nothing related to programming code A set of operations.
Stacks and Queues. DCS – SWC 2 Stacks A stack is an abstract data structure, with some special properties: –Insertion and deletion is only allowed at.
G.PULLAIAH COLLEGE OF ENGINEERING AND TECHNOLOGY
Week 4 - Friday CS221.
DATA STRUCTURES AND OBJECT ORIENTED PROGRAMMING IN C++
Queues Queues Queues.
Stacks and Queues.
Abstract Data Types Stack, Queue Amortized analysis
Stacks, Queues, and Deques
Stacks, Queues, and Deques
Stacks and Queues.
Abstract Data Types Stack, Queue Amortized analysis
Abstract Data Types Stack, Queue Amortized analysis
Haim Kaplan, Uri Zwick March 2018
Stacks, Queues, and Deques
Abstract Data Types Stack, Queue Amortized analysis
5.3 Implementing a Stack Chapter 5 – The Stack.
Presentation transcript:

1 Abstract Data Types Stack, Queue Amortized analysis Cormen: Ch 10, 17 (11, 18)

2 ADT is an interface It defines –the type of the data stored –operations, what each operation does (not how) –parameters of each operation

3 ADT Application Implementation of the Data structure חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים ממשק

4 ADT : how to work with Advantage: –Application programming can be done INDEPENDENTLY of implementation –If care about efficiency (complexity): BE CAREFUL!! Using the ADT the “wrong way” might become quite inefficient!!!

5 Example: Stacks Push(x,S) : Insert element x into S Pop(S) : Delete the last (time) element inserted into S Empty?(S): Return yes if S is empty Top(S): Return the last element inserted into S Size(S) Make-stack()

6 The Stack Data Abstraction push

7 The Stack Data Abstraction push pop push Last in, First out.

8 The Stack: Applications?? 1.REAL-LIFE: 1.Rifle 2.Some document handling? Last in, First out. 1.Computers/ Communications: 1.In some applications – LIFO preferred on FIFO 2.Program control + algorithm == a KEY

9 Evaluate an expression in postfix or Reverse Polish Notation InfixPostfix (2+ 3) * * ( (5 * (7 / 3) ) – (2 * 7) )5 7 3 / * 2 7 *- A stack application Application Implementation חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים ממשק

* A stack application 2 3 Application Implementation חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים ממשק

* A stack application 5 5

* A stack application 25

13 Pseudo = כאילו Combination of: 1.Programming (like) commands 2.“free style English” Allows to conveniently express and algorithm. See Cormen (one page) for his language constructs. No need for FORMAL syntax. (can deviate Cormen) A Word on Pseudo-code

14 S ← make-stack() while ( not eof ) do B ← read the next data; if B is an operand then push(B,S) else X ← pop(S) Y ← pop(S) Z ← Apply the operation B on X and Y push(Z,S) return(top(S)) Pseudo-code

15 Implementation We will be interested in algorithms to implement the ADT.. And their efficiency.. Application Implementation חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים ממשק

16 Using an array 1213 A A[0] A[1] t The stack is represented by the array A and variable t A[2] A[N-1]

17 Using an array 1213 A A[0] A[1] t make-stack(): Allocates the array A, which is of some fixed size N, sets t ← -1 The stack is represented by the array A and variable t A[2] A[N-1]

18 Operations 1213 A t size(S): return (t+1) empty?(S): return (t < 0) top(S): if empty?(S) then error else return A[t] A[N-1] A[0] A[1] A[2]

19 Pop 1213 A t pop(S): if empty?(S) then error else e ← A[t] t ← t – 1 return (e) A[N-1] A[0] A[1] A[2] pop(S)

20 Pop 1213 A t A[N-1] A[0] A[1] A[2] pop(S): if empty?(S) then error else e ← A[t] t ← t – 1 return (e) pop(S)

21 Push 1213 A t push(x,S): if size(S) = N then error else t ← t+1 A[t] ← x A[N-1] A[0] A[1] A[2] push(5,S)

22 Push 1215 A t push(x,S): if size(S) = N then error else t ← t+1 A[t] ← x A[N-1] A[0] A[1] A[2] push(5,S)

23 Implementation with lists top size=3 x.element x.next x

24 Implementation with lists top make-stack(): top ← null size ← 0 size=3

25 Operations top size(S): return (size) empty?(S): return (top = null) top(S): if empty?(S) then error else return top.element size=3

26 Pop top pop(S): if empty?(S) then error else e ← top.element top ← top.next size ← size-1 return (e) pop(S) size=3

27 Pop top pop(S): if empty?(S) then error else e ← top.element top ← top.next size ← size-1 return (e) pop(S) size=2

28 Garbage collection 1 5 top pop(S): if empty?(S) then error else e ← top.element top ← top.next size ← size-1 return (e) pop(S) size=2

29 Push 1 5 top size=2 push(x,S): n = new node n.element ← x n.next ← top top ← n size ← size + 1 push(5,S)

30 Push 1 5 top size=2 push(x,S): n = new node n.element ← x n.next ← top top ← n size ← size + 1 push(5,S) 5

31 Push 1 5 top size=2 push(x,S): n = new node n.element ← x n.next ← top top ← n size ← size + 1 push(5,S) 5

32 Push 1 5 top size=3 push(x,S): n = new node n.element ← x n.next ← top top ← n size ← size + 1 push(5,S) 5

33 Analysis Bound the running time of an operation on the worst-case As a function of the “size”, n, of the data structure Example: T(n) < 4n+7 Too detailed, most cases we are just interested in the order of growth

34 Why order of growth Precise cost can change from computer to computer From Programmer to programmer Anyhow MOORE  may go down by factor of next year

35 Big-O - קיים c ו- כך ש: דוגמא:

36 Big-O cg(n) f(n) n0n0

37 4n O(n 2 ) 4n 2 O(n 2 ) 2 n O(n 10 ) 10 O(1) 100n 3 +10n O(n 3 ) log 2 (n) O(log 10 (n)) More examples

38 The running time of our stack and queue operations Each operation takes O(1) time

39 Stacks via extendable arrays Array implementation difficulties: Pick large N: wasted space  Pick small N: stack is limited  Solution: –Pick moderate N, and: –When the array is full we will double its size (N) (DOUBLING)

40 Push push(x,S): /* N is size of array*/ if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x 121 A t A[N-1] A[0] A[1]

41 Push push(x,S): if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x A A[N-1] A[0] A[1] t push(5,S)

42 Push push(x,S): if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x A A[0] A[1] t push(5,S)

43 Push push(x,S): if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x A A[0] A[1] t push(5,S)

44 Push push(x,S): if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x t A[2N-1] A A[0] A[1] push(5,S)

45 Push push(x,S): /* N is array size */ if size(S) = N then {allocate a new array of size 2N copy the old array to the new one; N ← 2N } t ← t+1 A[t] ← x 5 A[2N-1] A A[0] A[1] t push(5,S)

46 Analysis An operation may take O(n) worst case time ! But that cannot happen often..

47 Amortized Analysis How long it takes to do m operations in the worst case ? Well, O(nm) Yes, but can it really take that long ?

48

49 x

50 xx

51 xx xxx

52 xx xxxx

53 xx xxxx xxxx x

54 xx xxxx xxxx xx

55 xx xxxx xxxx xxx

56 xx xxxx xxxx xxxx

57 xx xxxx xxxx xxxx xxxx xxxx x

58 xx xxxx xxxx xxxx xxxx xxxx xx

59 xx xxxx xxxx xxxx xxxx xxxx xxx

60 xxxx xxxx xxxx xxxx x After N-1 pushes that cost 1 we will have a push that costs 2N+1 Let N be the size of the array we just copied (half the size of the new array) Total time 3N for N pushes, 3 per push N xxxx

61 xx xxxx xxxx xxxx xxxx xxxx xxx 3+(2∙4+1)= 3∙4 7+(2∙8+1)= 3∙8 Total cost O(m) !! Start from the second row: z=2 1+(2∙2+1)=3∙2 z=4 z=8

62 Theorem: A sequence of m operations on a stack takes O(m) time We proved:

63 Amortized Analysis (The bank’s view) You come to do an operation with a bunch of tokens (amortized cost of the operation)

64 Operation

65 Operation You have to pay for each unit of work by a token (from your POCKET)

66 Operation

67 Operation If you have more tokens than work you put the remaining tokens in the bank

68 Operation

69 Operation If we have more work than tokens we pay with token from the bank

70 Operation If we have more work than tokens we pay with tokens from the bank

71 Amortized Analysis (The bank’s view) Suppose we prove that the bank is never in a deficit  The total work is no larger than the total number of tokens 3*m in our example if m is the number of operations

72 For a proof: Define exactly how each operation pays for its work, and how many tokens it puts in the bank Prove that the balance in the bank is always non-negative Count the total # of tokens – that’s your bound

73 “Easy” push Each push comes with 3 tokens (pocket) If it’s an easy push then we pay with one token for the single unit of work, and put two in the bank. A[N-1] A A[0] A[1] t

74 5 A[N-1] A A[0] A[1] t “Easy” push Imagine that the tokens in the bank are placed on the items of the stack We put one token on the item just inserted and another token on an arbitrary item without a token

A[N-1] A A[0] A[1] t

A[N-1] A A[0] A[1] t

77 “hard” push Tokens from the bank “pay” for copying the array into the larger array A[N-1] A A[0] A[1] t

78 Then you pay a token and put two in the bank as an “easy” push A t t “hard” push

79 Need to prove The balance is never negative: When we get to an expensive push there are enough tokens to pay for copying By induction: prove that after the i-th push following a copying there are 2i tokens in the bank N/2 easy pushes before the hard push  N tokens are at bank at the hard push t Starting with empty array

80 How many tokens we spent ? Each operation spent 3 tokens

81 Summary So the total # of tokens is 3m THM: A sequence of m operations takes O(m) time !! (we finished the proof) Each operation takes O(1) amortized time

82 Theorem: A sequence of m operations on a stack takes O(m) time proof (3). We formalize the bank as a potential function

83 Amortized(op) = actual(op) +  Define Let  be a potential function (can represent the amount in the bank) Out of pocket = on Operation + on  (bank)

84 Amortized(op 1 ) = actual(op 1 ) +  1 -  0 Amortized(op 2 ) = actual(op 2 ) +  2 -  1 Amortized(op m ) = actual(op m ) +  m -  (m-1) ………… +  i Amortized(op i ) =  i actual(op i ) +  m -  0  i Amortized(op i )   i actual(op i ) if  m -  0  0 We need to find  that gives a nontrivial statement Out of pocket = on Operation + on  (bank)

85 Example: Our extendable arrays Define: the potential of the stack t

86 Amortized(push) = actual(push) +  = 1 + 2(t’+1) – N - (2(t+1) – N) = 1+2(t’-t) = 3 Amortized(push) = N  = N (2 - N) = 3 Can we gain (make money)? No! #pop ≤ # push  amortz>= 2 With copying (hard): Without copying (easy): [ N (  after -  before )] Amortized(pop) = 1 +  = 1 + 2(t-1) – N - (2t – N) = -1

87 Amortized(op 1 ) = actual(op 1 ) +  1 -  0 Amortized(op 2 ) = actual(op 2 ) +  2 -  1 Amortized(op n ) = actual(op n ) +  n -  (n-1) ………… +  i Amortized(op i ) =  i actual(op i ) +  n -  0  i Amortized(op i )   i actual(op i ) if  n -  0  0 3m ≥

88 Summary So the total # of tokens is 3m  THM: A sequence of m operations starting from an empty stack takes O(m) time !! Each operations take O(1) amortized time

89 Queue Inject(x,Q) : Insert last element x into Q Pop(Q) : Delete the first element in Q Empty?(Q): Return yes if Q is empty Front(Q): Return the first element in Q Size(Q) Make-queue()

90 The Queue Data Abstraction inject

91 The Queue Data Abstraction inject pop First in, First out (FIFO).

92 Using an array A 5 A[0] A[1] t pop(Q) A[2] A[N-1]

93 Using an array 1425 A A[0] A[1] t pop(Q) A[2] A[N-1]

94 Using an array 1425 A A[0] A[1] t A[2] A[N-1] This would be inefficient if we insist that elements span a prefix of the array USE a MOVING ARRAY

95 Using an array A 5 A[0] A[1] r A[2] A[N-1] f A A[0] A[1] r A[2] f Empty queue f=r

96 Using an array A 5 A[0] A[1] r pop(Q) A[2] A[N-1] f

97 Using an array 142 A 5 A[0] A[1] A[2] A[N-1] f r pop(Q) inject(5,Q)

98 Using an array 142 A 55 A[0] A[1] A[2] A[N-1] f r pop(Q) inject(5,Q)

99 Using an array 142 A 555 A[0] A[1] A[2] A[N-1] f r pop(Q) inject(5,Q) pop(Q)

100 Using an array 2 A 555 A[0] A[1] A[2] A[N-1] f r pop(Q) inject(5,Q) pop(Q) pop(Q), inject(5,Q), pop(Q), inject(5,Q),……….

101 Using an array A 5555 A[0] A[1] r A[2] A[N-1] f pop(Q) inject(5,Q) pop(Q) pop(Q), inject(5,Q), pop(Q), inject(5,Q),………. Fall off the edge? 

102 Make the array “circular” 5 5 A 55 A[0] A[1] r A[2] A[N-1] f Pop(Q), inject(5,Q), pop(Q), inject(5,Q),……….

103 Operations empty?(Q): return (f = r) top(Q): if empty?(Q) then error else return A[f] 142 A 5 A[0] A[1] A[2] A[N-1] f r

104 Operations size(Q): if (r >= f) then return (r-f) else return N-(f-r) 142 A 5 A[0] A[1] A[2] A[N-1] f r

105 Operations size(Q): if (r >= f) then return (r-f) else return N-(f-r) 5 5 A 55 A[0] A[1] r A[2] A[N-1] f

106 Pop pop(Q) 142 A 5 A[0] A[1] A[2] f r pop(Q): if empty?(Q) then error else e ← A[f] f ← (f + 1) mod N return (e)

107 Pop pop(Q): if empty?(Q) then error else e ← A[f] f ← (f + 1) mod N return (e) pop(Q) 142 A 5 A[0] A[1] A[2] f r

108 Inject inject(x,Q): if size(Q) = N-1 then error else A[r] ← x r ← (r+1) mod N inject(5,Q) 42 A 5 A[0] A[1] A[2] f r Why? f=r  empty

109 Inject inject(x,Q): if size(Q) = N-1 then error else A[r] ← x r ← (r+1) mod N inject(5,Q) 42 A 55 A[0] A[1] A[2] f r Or could do doubling

110 Implementation with lists head size=3 tail inject(4,Q)

111 Implementation with lists head size=3 tail inject(4,Q) 4

112 Implementation with lists head size=3 tail inject(4,Q) 4 Complete the details by yourself

113 Continue in DS2…. Slide 26

114 Double ended queue (deque) Push(x,D) : Insert x as the first in D Pop(D) : Delete the first element of D Inject(x,D): Insert x as the last in D Eject(D): Delete the last element of D Size(D) Empty?(D) Make-deque()

115 Implementation with doubly linked lists 5 head size=2 tail 13 x.next x.element x.prev x

116 Empty list head size=0 tail We use two sentinels here to make the code simpler

117 Push push(x,D): n = new node n.element ← x n.next ← head.next (head.next).prev ← n head.next ← n n.prev ← head size ← size head size=1 tail

118 push(x,D): n = new node n.element ← x n.next ← head.next (head.next).prev ← n head.next ← n n.prev ← head size ← size head size=1 tail push(4,D) 4

119 push(x,D): n = new node n.element ← x n.next ← head.next (head.next).prev ← n head.next ← n n.prev ← head size ← size head size=1 tail push(4,D) 4

120 push(x,D): n = new node n.element ← x n.next ← head.next (head.next).prev ← n head.next ← n n.prev ← head size ← size head size=1 tail push(4,D) 4

121 push(x,D): n = new node n.element ← x n.next ← head.next (head.next).prev ← n head.next ← n n.prev ← head size ← size head size=2 tail push(4,D) 4

122 Implementations of the other operations are similar Try by yourself