Queue.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. <?php
  2. /**
  3. * A simple array-backed queue, based off of the classic Okasaki
  4. * persistent amortized queue. The basic idea is to maintain two
  5. * stacks: an input stack and an output stack. When the output
  6. * stack runs out, reverse the input stack and use it as the output
  7. * stack.
  8. *
  9. * We don't use the SPL implementation because it's only supported
  10. * on PHP 5.3 and later.
  11. *
  12. * Exercise: Prove that push/pop on this queue take amortized O(1) time.
  13. *
  14. * Exercise: Extend this queue to be a deque, while preserving amortized
  15. * O(1) time. Some care must be taken on rebalancing to avoid quadratic
  16. * behaviour caused by repeatedly shuffling data from the input stack
  17. * to the output stack and back.
  18. */
  19. class HTMLPurifier_Queue {
  20. private $input;
  21. private $output;
  22. public function __construct($input = array()) {
  23. $this->input = $input;
  24. $this->output = array();
  25. }
  26. /**
  27. * Shifts an element off the front of the queue.
  28. */
  29. public function shift() {
  30. if (empty($this->output)) {
  31. $this->output = array_reverse($this->input);
  32. $this->input = array();
  33. }
  34. if (empty($this->output)) {
  35. return NULL;
  36. }
  37. return array_pop($this->output);
  38. }
  39. /**
  40. * Pushes an element onto the front of the queue.
  41. */
  42. public function push($x) {
  43. array_push($this->input, $x);
  44. }
  45. /**
  46. * Checks if it's empty.
  47. */
  48. public function isEmpty() {
  49. return empty($this->input) && empty($this->output);
  50. }
  51. }