abstract data types queue dequeue amortized analysis n.
Skip this Video
Loading SlideShow in 5 Seconds..
Abstract Data Types Queue + Dequeue Amortized analysis PowerPoint Presentation
Download Presentation
Abstract Data Types Queue + Dequeue Amortized analysis

play fullscreen
1 / 50
Download Presentation

Abstract Data Types Queue + Dequeue Amortized analysis - PowerPoint PPT Presentation

lilli
102 Views
Download Presentation

Abstract Data Types Queue + Dequeue Amortized analysis

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Abstract Data TypesQueue + DequeueAmortized analysis

  2. 5 4 17 21 Q 5 4 17 21 Can one Implement A Queue with stacks? • You are given the STACK ABSTRACT data structure (1, 2 .. as many as you want) • Can you use it to implement a queue S2 S1

  3. Implementation of Queue with stacks S2 S1 13 5 4 17 21 size=5 inject(x,Q): push(x,S2); size ← size + 1 inject(2,Q)

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

  5. Implementation of a Queue with stacks S2 S1 13 5 4 17 21 2 size=6 inject(x,Q): push(x,S2); size ← size + 1 inject(2,Q)

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

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

  8. Pop S2 S1 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(Q)

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

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

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

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

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

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

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

  16. Analysis • O(n) worst case time per operation

  17. Amortized Analysis • How long it takes to perform m operations on the worst case ? • O(nm) • Is this tight ?

  18. Key Observation • An expensive operation cannot occur too often !

  19. 2 7 5 4 21 S1 S2 Amortized complexity THM: If we start with an empty queue and perform m operations then it takes O(m) time Proof: • No element moves from S2 to S1 • Entrance at S1, exit at S2. • Every element: • Enters S1 exactly once • Moves from S1 to S2 at most once • Exits S2 at most once •  #ops per element ≤ 3 • m operations  #elements ≤ m  work ≤ 3 m

  20. Potential based Proof (on your own) Consider Think of Φ as accumulation of easy operations covering for future potential “damage” 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)

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

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

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

  24. Push head 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

  25. 4 head 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)

  26. 4 head 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)

  27. 4 head 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)

  28. 4 head 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)

  29. Implementation with stacks S2 S1 13 5 4 17 21 size=5 push(x,D): push(x,S1) push(2,D)

  30. Implementation with stacks S2 S1 2 13 5 4 17 21 size=6 push(x,D): push(x,S1) push(2,D)

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

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

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

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

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

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

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

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

  39. Split S2 S1 5 4 17 21 S3

  40. Split S2 S1 5 4 17 S3 21

  41. Split S2 S1 5 4 S3 17 21

  42. Split S2 S1 4 5 S3 17 21

  43. Split S2 S1 5 4 S3 17 21

  44. Split S2 S1 17 5 4 S3 21

  45. Split S2 S1 17 21 5 4 S3

  46. Split (same thing in reverse) S2 S1 5 4 S3

  47. 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 while (i ≤⌊d/2⌋) do x ←pop(S3) push(x,S2) i ← i+1

  48. Analysis • O(n) worst case time per operation

  49. Thm: If we start with an empty deque and perform m operations then it takes O(m) time

  50. A better bound Consider Think of Φ as accumulation of easy operations covering for future potential “damage” 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| (S2 empty) So the amortized time is O(1)