57 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			57 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A simple array-backed queue, based off of the classic Okasaki
							 | 
						||
| 
								 | 
							
								 * persistent amortized queue.  The basic idea is to maintain two
							 | 
						||
| 
								 | 
							
								 * stacks: an input stack and an output stack.  When the output
							 | 
						||
| 
								 | 
							
								 * stack runs out, reverse the input stack and use it as the output
							 | 
						||
| 
								 | 
							
								 * stack.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * We don't use the SPL implementation because it's only supported
							 | 
						||
| 
								 | 
							
								 * on PHP 5.3 and later.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Exercise: Prove that push/pop on this queue take amortized O(1) time.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Exercise: Extend this queue to be a deque, while preserving amortized
							 | 
						||
| 
								 | 
							
								 * O(1) time.  Some care must be taken on rebalancing to avoid quadratic
							 | 
						||
| 
								 | 
							
								 * behaviour caused by repeatedly shuffling data from the input stack
							 | 
						||
| 
								 | 
							
								 * to the output stack and back.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class HTMLPurifier_Queue {
							 | 
						||
| 
								 | 
							
								    private $input;
							 | 
						||
| 
								 | 
							
								    private $output;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function __construct($input = array()) {
							 | 
						||
| 
								 | 
							
								        $this->input = $input;
							 | 
						||
| 
								 | 
							
								        $this->output = array();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Shifts an element off the front of the queue.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function shift() {
							 | 
						||
| 
								 | 
							
								        if (empty($this->output)) {
							 | 
						||
| 
								 | 
							
								            $this->output = array_reverse($this->input);
							 | 
						||
| 
								 | 
							
								            $this->input = array();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (empty($this->output)) {
							 | 
						||
| 
								 | 
							
								            return NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return array_pop($this->output);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Pushes an element onto the front of the queue.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function push($x) {
							 | 
						||
| 
								 | 
							
								        array_push($this->input, $x);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Checks if it's empty.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function isEmpty() {
							 | 
						||
| 
								 | 
							
								        return empty($this->input) && empty($this->output);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |