Presentation is loading. Please wait.

Presentation is loading. Please wait.

Abstract Data Types Stack, Queue Amortized analysis

Similar presentations


Presentation on theme: "Abstract Data Types Stack, Queue Amortized analysis"— Presentation transcript:

1 Abstract Data Types Stack, Queue Amortized analysis

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

3 Implementation with lists
head size=3 12 1 5 tail inject(4,Q)

4 Implementation with lists
head size=3 12 1 5 4 tail inject(4,Q)

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

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

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

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

9 Push size=1 5 push(x,D): n = new node n.element ←x n.next ← head.next
tail size=1 5 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

10 4 size=1 5 push(x,D): n = new node n.element ←x n.next ← head.next
tail size=1 5 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 push(4,D)

11 4 size=1 5 push(x,D): n = new node n.element ←x n.next ← head.next
tail size=1 5 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 push(4,D)

12 4 size=1 5 push(x,D): n = new node n.element ←x n.next ← head.next
tail size=1 5 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 push(4,D)

13 4 size=2 5 push(x,D): n = new node n.element ←x n.next ← head.next
tail size=2 5 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 push(4,D)

14 Implementations of the other operations are similar
Try by yourself

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

16 Implementation with stacks
13 size=5 inject(x,Q): push(x,S2); size ← size + 1 inject(2,Q)

17 Implementation with stacks
13 size=5 inject(x,Q): push(x,S2); size ← size + 1 inject(2,Q)

18 Implementation with stacks
13 size=6 inject(x,Q): push(x,S2); size ← size + 1 inject(2,Q)

19 Pop S1 S2 13 5 4 17 21 2 size=6 pop(Q): if empty?(Q) error
size=6 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q)

20 Pop S2 S1 5 4 17 21 2 size=6 pop(Q): if empty?(Q) error
size=6 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q)

21 Pop S2 S1 5 4 17 21 2 size=5 pop(Q): if empty?(Q) error
size=5 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

22 Pop S1 S2 2 5 4 17 21 size=5 pop(Q): if empty?(Q) error
size=5 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

23 Pop S1 S2 21 2 5 4 17 size=5 pop(Q): if empty?(Q) error
size=5 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

24 Pop S1 S2 17 21 2 5 4 size=5 pop(Q): if empty?(Q) error
5 4 size=5 pop(Q): if empty?(Q) error if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

25 Pop S1 S2 4 17 21 2 5 size=5 pop(Q): if empty?(Q) error
if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

26 Pop S1 S2 5 4 17 21 2 size=5 pop(Q): if empty?(Q) error
if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

27 Pop S1 S2 4 17 21 2 size=4 pop(Q): if empty?(Q) error
if empty?(S1) then move(S2, S1) pop( S1); size ← size -1 pop(Q) pop(D)

28 move(S2, S1) while not empty?(S2) do x ← pop(S2) push(x,S1)

29 Analysis O(n) worst case time per operation

30 Amortized Analysis How long it takes to perform m operations on the worst case ? O(nm) Really ?

31 Key Observation An expensive operation cannot occur too often !

32 The potential formalism
The potential is in fact the bank

33 Define: a potential function 
Amortized(op) = actual(op) + 

34 + Amortized(op1) = actual(op1) + 1- 0
Amortized(opn) = actual(opn) + n- (n-1) iAmortized(opi) = iactual(opi) + n- 0 iAmortized(opi)  iactual(opi) if n- 0  0

35 A better bound Consider Recall that: Amortized(op) = actual(op) + ΔΦ
This is O(1) if a move does not occur Say we move S2: Then the actual time is |S2| + O(1) ΔΦ = -|S2| So the amortized time is O(1)

36 Conclusion If we start with an empty queue and perform m operations then its takes O(m) time

37

38 Back to deques Alternative implementation using stacks

39 Implementation with stacks
13 size=5 push(x,D): push(x,S1) push(2,D)

40 Implementation with stacks
2 13 size=6 push(x,D): push(x,S1) push(2,D)

41 Pop S1 S2 2 13 5 4 17 21 size=6 pop(D): if empty?(D) error
size=6 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D)

42 Pop S1 S2 13 5 4 17 21 size=5 pop(D): if empty?(D) error
size=5 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D) pop(D)

43 Pop S2 S1 5 4 17 21 size=4 pop(D): if empty?(D) error
size=4 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D) pop(D)

44 Pop S2 S1 5 4 17 21 size=4 pop(D): if empty?(D) error
size=4 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D)

45 Pop S2 S1 5 4 17 21 size=4 pop(D): if empty?(D) error
size=4 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D)

46 Pop S2 S1 5 4 17 21 size=4 pop(D): if empty?(D) error
5 4 S2 17 21 size=4 pop(D): if empty?(D) error if empty?(S1) then split(S2, S1) pop( S1) pop(D)

47 Pop S1 S2 4 17 21 size=4 pop(D): if empty?(D) error
if empty?(S1) then split(S2, S1) pop( S1) pop(D)

48 Pop S1 S2 4 17 21 size=3 pop(D): if empty?(D) error
if empty?(S1) then split(S2, S1) pop( S1) pop(D)

49 Split S1 S2 S3

50 Split S1 S2 S3 21

51 Split S1 S2 5 4 S3 17 21

52 Split S1 S2 4 5 S3 17 21

53 Split S1 S2 5 4 S3 17 21

54 Split S1 17 S2 5 4 S3 21

55 Split S1 S2 5 4 17 21 S3

56 split(S2, S1) S3 ← make-stack() d ← size(S2) while (i ≤ ⌊d/2⌋) do x ← pop(S2) push(x,S3) i ← i+1 while (i ≤ ⌈d/2⌉) do x ← pop(S2) push(x,S1) i ← i+1 x ← pop(S3) push(x,S2) i ← i+1

57 Analysis O(n) worst case time per operation

58 Amortized Analysis How long it takes to perform m operations on the worst case ? O(nm) Really ?

59 Key Observation An expensive operation cannot occur too often !

60 A better bound Consider Recall that: Amortized(op) = actual(op) + ΔΦ
This is O(1) if no splitting occurs Say we split S1: Then the actual time is |S1| + O(1) ΔΦ = -|S1| So the amortized time is O(1)

61 Conclusion If we start with an empty deque and perform m operations then its takes O(m) time


Download ppt "Abstract Data Types Stack, Queue Amortized analysis"

Similar presentations


Ads by Google