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);
 | 
						|
    }
 | 
						|
}
 |