Abstract Data Types Stack, Queue Amortized analysis

109
1 Abstract Data Types Stack, Queue Amortized analysis

description

Abstract Data Types Stack, Queue Amortized analysis. ADT is an interface. It defines the type of the data stored operations, what each operation does (not how) parameters of each operation. ADT. Application. חוזה בין מתכנת האפליקציה ומיישם מבנה הנתונים. ממשק. Implementation of the - PowerPoint PPT Presentation

Transcript of Abstract Data Types Stack, Queue Amortized analysis

Page 1: Abstract Data Types Stack, Queue Amortized analysis

1

Abstract Data TypesStack, Queue

Amortized analysis

Page 2: Abstract Data Types Stack, Queue Amortized analysis

2

ADT is an interface

• It defines– the type of the data stored– operations, what each operation does

(not how)– parameters of each operation

Page 3: Abstract Data Types Stack, Queue Amortized analysis

3

ADT

Application

Implementation of theData structure

חוזה בין מתכנת האפליקציה

ומיישם מבנה הנתונים

ממשק

Page 4: Abstract Data Types Stack, Queue Amortized analysis

4

Example: Stacks

• Push(x,S) : Insert element x into S• Pop(S) : Delete the last 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()

Page 5: Abstract Data Types Stack, Queue Amortized analysis

5

The Stack Data Abstraction

push

push

push

Page 6: Abstract Data Types Stack, Queue Amortized analysis

6

The Stack Data Abstraction

push

push

push

pop

push

Last in,First out.

Page 7: Abstract Data Types Stack, Queue Amortized analysis

7

• Evaluate an expression in postfix or Reverse Polish Notation

Infix Postfix

(2+ 3) * 5 2 3 + 5 *

( (5 * (7 / 3) ) – (2 * 7) ) 5 7 3 / * 2 7 *-

A stack application

Page 8: Abstract Data Types Stack, Queue Amortized analysis

8

2 3 + 5 *

A stack application

23

Page 9: Abstract Data Types Stack, Queue Amortized analysis

9

2 3 + 5 *

A stack application

55

Page 10: Abstract Data Types Stack, Queue Amortized analysis

10

2 3 + 5 *

A stack application

25

Page 11: Abstract Data Types Stack, Queue Amortized analysis

11

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

Page 12: Abstract Data Types Stack, Queue Amortized analysis

12

Implementation

• We will be interested in algorithms to implement the ADT..

• And their efficiency..

Page 13: Abstract Data Types Stack, Queue Amortized analysis

13

Using an array

12 1 3A

A[0] A[1]

t

The stack is represented by the array A and variable t

A[2] A[N-1]

1213

Page 14: Abstract Data Types Stack, Queue Amortized analysis

14

Using an array

12 1 3A

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]

Page 15: Abstract Data Types Stack, Queue Amortized analysis

15

Operations

12 1 3A

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]

Page 16: Abstract Data Types Stack, Queue Amortized analysis

16

Pop

12 1 3A

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)

Page 17: Abstract Data Types Stack, Queue Amortized analysis

17

Pop

12 1 3A

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)

Page 18: Abstract Data Types Stack, Queue Amortized analysis

18

Push

12 1 3A

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)

Page 19: Abstract Data Types Stack, Queue Amortized analysis

19

Push

12 1 5A

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)

Page 20: Abstract Data Types Stack, Queue Amortized analysis

20

Implementation with lists

12 1 5

top

size=3

x.element

x.nextx

Page 21: Abstract Data Types Stack, Queue Amortized analysis

21

Implementation with lists

12 1 5

top

make-stack(): top ← null size ← 0

size=3

Page 22: Abstract Data Types Stack, Queue Amortized analysis

22

Operations

12 1 5

top

size(S): return (size)

empty?(S): return (top = null)

top(S): if empty?(S) then error else return top.element

size=3

Page 23: Abstract Data Types Stack, Queue Amortized analysis

23

Pop

12 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=3

Page 24: Abstract Data Types Stack, Queue Amortized analysis

24

Pop

12 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

Page 25: Abstract Data Types Stack, Queue Amortized analysis

25

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

Page 26: Abstract Data Types Stack, Queue Amortized analysis

26

Push

1 5

topsize=2

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

Page 27: Abstract Data Types Stack, Queue Amortized analysis

27

Push

1 5

topsize=2

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

5

Page 28: Abstract Data Types Stack, Queue Amortized analysis

28

Push

1 5

topsize=2

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

5

Page 29: Abstract Data Types Stack, Queue Amortized analysis

29

Push

1 5

topsize=3

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

5

Page 30: Abstract Data Types Stack, Queue Amortized analysis

30

Analysis

• Bound the running time of an operation on the worst-case

• As a function of the “size”, n, of the data structure

• T(n) < 4n+7• Too detailed, we are just interested

in the order of growth

Page 31: Abstract Data Types Stack, Queue Amortized analysis

31

Big-O

) ו- כך ש:c - קיים ) ( ( ))T n O f n0n

0)()( nnnfcnT

דוגמא:2

( ) ( 1)T n n

)(4)1(222nOnn

Page 32: Abstract Data Types Stack, Queue Amortized analysis

32

Big-O

))(()( ngOnf

cg(n)

f(n)

n0

Page 33: Abstract Data Types Stack, Queue Amortized analysis

33

• 4n O(n2)

• 4n2 O(n2)

• 2n O(n10)

• 10 O(1)

• 100n3+10n O(n3)

• log2(n) O(log10(n))

More examples

Page 34: Abstract Data Types Stack, Queue Amortized analysis

34

The running time of our stack and queue operations

• Each operation takes O(1) time

Page 35: Abstract Data Types Stack, Queue Amortized analysis

35

Stacks via extendable arrays

• We do not want our implementation using arrays to be limited to only N elements

• When the array is full we will double its size

Page 36: Abstract Data Types Stack, Queue Amortized analysis

36

Push

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

12 1A

t

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

Page 37: Abstract Data Types Stack, Queue Amortized analysis

37

Push

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

12 1 3 3A 4 5 7 3 2 8 1

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

t

push(5,S)

Page 38: Abstract Data Types Stack, Queue Amortized analysis

38

Push

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

push(5,S)

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

Page 39: Abstract Data Types Stack, Queue Amortized analysis

39

Push

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

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

12 1 3 3 4 5 7 3 2 8 1

t

Page 40: Abstract Data Types Stack, Queue Amortized analysis

40

Push

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

t

A[2N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

push(5,S)

Page 41: Abstract Data Types Stack, Queue Amortized analysis

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 t ←t+1 A[t] ← x

5

A[2N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

push(5,S)

Page 42: Abstract Data Types Stack, Queue Amortized analysis

42

Analysis

• An operation may take O(n) worst case time !

• But that cannot happen often..

Page 43: Abstract Data Types Stack, Queue Amortized analysis

43

Amortized Analysis

• How long it takes to do m operations ?

• Well, O(nm)

• Yes, but can it really take that long ?

Page 44: Abstract Data Types Stack, Queue Amortized analysis

44

Page 45: Abstract Data Types Stack, Queue Amortized analysis

45

x

Page 46: Abstract Data Types Stack, Queue Amortized analysis

46

x x

Page 47: Abstract Data Types Stack, Queue Amortized analysis

47

x x

x x x

Page 48: Abstract Data Types Stack, Queue Amortized analysis

48

x x

x x x x

Page 49: Abstract Data Types Stack, Queue Amortized analysis

49

x x

x x x x

x x x x x

Page 50: Abstract Data Types Stack, Queue Amortized analysis

50

x x

x x x x

x x x x x x

Page 51: Abstract Data Types Stack, Queue Amortized analysis

51

x x

x x x x

x x x x x x x

Page 52: Abstract Data Types Stack, Queue Amortized analysis

52

x x

x x x x

x x x x x x x x

Page 53: Abstract Data Types Stack, Queue Amortized analysis

53

x x

x x x x

x x x x x x x x

x x x x x x x x x

Page 54: Abstract Data Types Stack, Queue Amortized analysis

54

x x

x x x x

x x x x x x x x

x x x x x x x x x x

Page 55: Abstract Data Types Stack, Queue Amortized analysis

55

x x

x x x x

x x x x x x x x

x x x x x x x x x x x

Page 56: Abstract Data Types Stack, Queue Amortized analysis

56

x x

x x x x

x x x x x x x x

x x x x x x x x x x x

Only after z-1 pushes that cost 1 we will have a push that costs 2z+1

Let z be the size of the array we just copied

Page 57: Abstract Data Types Stack, Queue Amortized analysis

57

x x

x x x x

x x x x x x x x

x x x x x x x x x x x

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

Page 58: Abstract Data Types Stack, Queue Amortized analysis

58

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

proof.

Page 59: Abstract Data Types Stack, Queue Amortized analysis

59

Amortized Analysis (The bank’s view)

• We will have a bank

• An operation can either pay a token for a unit of work by itself, or take a token from the bank to pay for it

• An operation can put tokens in the bank

• If the bank never has a negative balance then the total # of tokens spent by the operations bounds the total work

Page 60: Abstract Data Types Stack, Queue Amortized analysis

60

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

Page 61: Abstract Data Types Stack, Queue Amortized analysis

61

“Easy” push

• when we push an item, we also put ≤ two tokens, one on the item which we insert, and one on another item if there is some item without a token

A[N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

Page 62: Abstract Data Types Stack, Queue Amortized analysis

62

5

A[N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

“Easy” push

• when we push an item, we also put ≤ two tokens, one on the item which we insert, and one on another item if there is some item without a token

Page 63: Abstract Data Types Stack, Queue Amortized analysis

63

5 6

A[N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

Page 64: Abstract Data Types Stack, Queue Amortized analysis

64

5 6 6 7 1 10 4 67 2 5 7

A[N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

Page 65: Abstract Data Types Stack, Queue Amortized analysis

65

“hard” push

• Tokens from the bank “pay” for copying the array into the larger array

5 6 6 7 1 10 4 67 2 5 7

A[N-1]

12 1 3 3A 4 5 7 3 2 8 1

A[0] A[1]

t

Page 66: Abstract Data Types Stack, Queue Amortized analysis

66

• Then you pay a token and put two in the bank as an “easy” push

5 6 6 7 1 10 4 67 2 5 712 1 3 3 4 5 7 3 2 8 1 A

t

5 6 6 7 1 10 4 67 2 5 712 1 3 3 4 5 7 3 2 8 1 4

t

“hard” push

Page 67: Abstract Data Types Stack, Queue Amortized analysis

67

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

Page 68: Abstract Data Types Stack, Queue Amortized analysis

68

How many tokens we spent ?

• Each operation spent 3 tokens

Page 69: Abstract Data Types Stack, Queue Amortized analysis

69

Summary

• So the total # of tokens is 3mTHM: A sequence of m operations takes

O(m) time !! (we finished the proof)

• Each operation takes O(1) amortized time

Page 70: Abstract Data Types Stack, Queue Amortized analysis

70

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

proof (2) .

• We formalize the bank as a potential function

Page 71: Abstract Data Types Stack, Queue Amortized analysis

71

Amortized(op) = actual(op) +

Define

Define: a potential function

Page 72: Abstract Data Types Stack, Queue Amortized analysis

72

Amortized(op1) = actual(op1) + 1- 0

Amortized(op2) = actual(op2) + 2- 1

Amortized(opn) = actual(opn) + n- (n-1)

……

+

iAmortized(opi) = iactual(opi) + n- 0

iAmortized(opi) iactual(opi) if n- 0 0

Page 73: Abstract Data Types Stack, Queue Amortized analysis

73

Example: Our extendable arrays

Define a potential of the stack

2( 1) 2( 1) 0( )

0

t N if t NS

Otherwise

Page 74: Abstract Data Types Stack, Queue Amortized analysis

74

Amortized(push) = actual(push) + =

1 + 2(t+2) – N - (2(t+1) – N) = 3

Amortized(push) = N + 1 + =

N + 1 + (2 - N) = 3

Amortized(pop) = 1 + =

1 + 2(t-1) – N - (2t – N) = -1

With copying:

Without copying:

Page 75: Abstract Data Types Stack, Queue Amortized analysis

75

Amortized(op1) = actual(op1) + 1- 0

Amortized(op2) = actual(op2) + 2- 1

Amortized(opn) = actual(opn) + n- (n-1)

……

+

iAmortized(opi) = iactual(opi) + n- 0

iAmortized(opi) iactual(opi) if n- 0 03m ≥

Page 76: Abstract Data Types Stack, Queue Amortized analysis

76

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

Page 77: Abstract Data Types Stack, Queue Amortized analysis

77

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

Page 78: Abstract Data Types Stack, Queue Amortized analysis

78

The Queue Data Abstraction

inject

inject

Page 79: Abstract Data Types Stack, Queue Amortized analysis

79

The Queue Data Abstraction

inject

inject

inject

inject

popFirst in,First out (FIFO).

Page 80: Abstract Data Types Stack, Queue Amortized analysis

80

Using an array

12 1 4 2A 5

A[0] A[1]

t

pop(Q)

A[2] A[N-1]

Page 81: Abstract Data Types Stack, Queue Amortized analysis

81

Using an array

1 4 2 5A

A[0] A[1]

t

pop(Q)

A[2] A[N-1]

Page 82: Abstract Data Types Stack, Queue Amortized analysis

82

Using an array

1 4 2 5A

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

Page 83: Abstract Data Types Stack, Queue Amortized analysis

83

Using an array

12 1 4 2A 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

Page 84: Abstract Data Types Stack, Queue Amortized analysis

84

Using an array

12 1 4 2A 5

A[0] A[1]

r

pop(Q)

A[2] A[N-1]

f

Page 85: Abstract Data Types Stack, Queue Amortized analysis

85

Using an array

1 4 2A 5

A[0] A[1]

A[2] A[N-1]

f r

pop(Q)inject(5,Q)

Page 86: Abstract Data Types Stack, Queue Amortized analysis

86

Using an array

1 4 2A 5 5

A[0] A[1]

A[2] A[N-1]

f r

pop(Q)inject(5,Q)inject(5,Q)

Page 87: Abstract Data Types Stack, Queue Amortized analysis

87

Using an array

1 4 2A 5 5 5

A[0] A[1]

A[2] A[N-1]

f r

pop(Q)inject(5,Q)inject(5,Q)pop(Q)pop(Q)

Page 88: Abstract Data Types Stack, Queue Amortized analysis

88

Using an array

2A 5 5 5

A[0] A[1]

A[2] A[N-1]

f r

pop(Q)inject(5,Q)inject(5,Q)pop(Q)pop(Q)pop(Q), inject(5,Q), pop(Q), inject(5,Q),……….

Page 89: Abstract Data Types Stack, Queue Amortized analysis

89

Using an array

A 5 5 5 5

A[0] A[1]

r

A[2] A[N-1]

f

pop(Q)inject(5,Q)inject(5,Q)pop(Q)pop(Q)pop(Q), inject(5,Q), pop(Q), inject(5,Q),……….

Page 90: Abstract Data Types Stack, Queue Amortized analysis

90

Make the array “circular”

5 5 A 5 5

A[0] A[1]

r

A[2] A[N-1]

f

Pop(Q), inject(5,Q), pop(Q), inject(5,Q),……….

Page 91: Abstract Data Types Stack, Queue Amortized analysis

91

Operations

empty?(Q): return (f = r)

top(Q): if empty?(Q) then error else return A[f]

1 4 2A 5

A[0] A[1]

A[2] A[N-1]

f r

Page 92: Abstract Data Types Stack, Queue Amortized analysis

92

Operations

size(Q): if (r >= f) then return (r-f) else return N-(f-r)

1 4 2A 5

A[0] A[1]

A[2] A[N-1]

f r

Page 93: Abstract Data Types Stack, Queue Amortized analysis

93

Operations

size(Q): if (r >= f) then return (r-f) else return N-(f-r)

5 5 A 5 5

A[0] A[1]

r

A[2] A[N-1]

f

Page 94: Abstract Data Types Stack, Queue Amortized analysis

94

Pop

pop(Q)

1 4 2A 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)

Page 95: Abstract Data Types Stack, Queue Amortized analysis

95

Pop

pop(Q): if empty?(Q) then error else e ←A[f] f ← (f + 1) mod N return (e)

pop(Q)

1 4 2A 5

A[0] A[1]

A[2]

f r

Page 96: Abstract Data Types Stack, Queue Amortized analysis

96

Inject

inject(x,Q): if size(Q) = N-1 then error else A[r] ← x r ← (r+1) mod N

inject(5,Q)

4 2A 5

A[0] A[1]

A[2]

f r

Page 97: Abstract Data Types Stack, Queue Amortized analysis

97

Inject

inject(x,Q): if size(Q) = N-1 then error else A[r] ← x r ← (r+1) mod N

inject(5,Q)

4 2A 5 5

A[0] A[1]

A[2]

f r

Page 98: Abstract Data Types Stack, Queue Amortized analysis

98

Implementation with lists

12 1 5

headsize=3

tail

inject(4,Q)

Page 99: Abstract Data Types Stack, Queue Amortized analysis

99

Implementation with lists

12 1 5

headsize=3

tail

inject(4,Q)

4

Page 100: Abstract Data Types Stack, Queue Amortized analysis

100

Implementation with lists

12 1 5

headsize=3

tail

inject(4,Q)

4

Complete the details by yourself

Page 101: Abstract Data Types Stack, Queue Amortized analysis

101

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

Page 102: Abstract Data Types Stack, Queue Amortized analysis

102

Implementation with doubly linked lists

5

head

size=2

tail

13

x.next

x.element

x.prev

x

Page 103: Abstract Data Types Stack, Queue Amortized analysis

103

Empty list

head

size=0

tail

We use two sentinels here to make the code simpler

Page 104: Abstract Data Types Stack, Queue Amortized analysis

104

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 + 1

5

head

size=1

tail

Page 105: Abstract Data Types Stack, Queue Amortized analysis

105

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 + 1

5

head

size=1

tail

push(4,D)

4

Page 106: Abstract Data Types Stack, Queue Amortized analysis

106

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 + 1

5

head

size=1

tail

push(4,D)

4

Page 107: Abstract Data Types Stack, Queue Amortized analysis

107

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 + 1

5

head

size=1

tail

push(4,D)

4

Page 108: Abstract Data Types Stack, Queue Amortized analysis

108

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 + 1

5

head

size=2

tail

push(4,D)

4

Page 109: Abstract Data Types Stack, Queue Amortized analysis

109

Implementations of the other operations are similar

• Try by yourself