php 雙向隊列類

(deque,全名double-ended queue)是一種具備隊列和棧的性質的數據結構。雙向隊列中的元素能夠從兩端彈出,其限定插入和刪除操做在表的兩端進行。php


在實際使用中,還能夠有輸出受限的雙向隊列(即一個端點容許插入和刪除,另外一個端點只容許插入的雙向隊列)和輸入受限的雙向隊列(即一個端點容許插入和刪除,另外一個端點只容許刪除的雙向隊列)。而若是限定雙向隊列從某個端點插入的元素只能從該端點刪除,則該雙向隊列就蛻變爲兩個棧底相鄰的棧了。
前端


DEQue.class.php後端

<?php
/** php 雙向隊列。支持限定隊列長度,輸入受限,輸出受限,及輸出必須與輸入同端幾種設置
*   Date:   2014-04-30
*   Author: fdipzone
*   Ver:    1.0
*
*   Func:
*   public  frontAdd     前端入列
*   public  frontRemove  前端出列
*   public  rearAdd      後端入列
*   pulbic  rearRemove   後端出列
*   public  clear        清空對列
*   public  isFull       判斷對列是否已滿
*   private getLength    獲取對列長度
*   private setAddNum    記錄入列,輸出依賴輸入時調用
*   private setRemoveNum 記錄出列,輸出依賴輸入時調用
*   private checkRemove  檢查是否輸出依賴輸入
*/

class DEQue{ // class start

    private $_queue = array(); // 對列
    private $_maxLength = 0;   // 對列最大長度,0表示不限
    private $_type = 0;        // 對列類型
    private $_frontNum = 0;    // 前端插入的數量
    private $_rearNum = 0;     // 後端插入的數量


    /** 初始化
    * @param $type       對列類型
    *                    1:兩端都可輸入輸出
    *                    2:前端只能輸入,後端可輸入輸出
    *                    3:前端只能輸出,後端可輸入輸出
    *                    4:後端只能輸入,前端可輸入輸出
    *                    5:後端只能輸出,前端可輸入輸出
    *                    6:兩端都可輸入輸出,在哪端輸入只能從哪端輸出
    * @param $maxlength  對列最大長度
    */
    public function __construct($type=1, $maxlength=0){
        $this->_type = in_array($type, array(1,2,3,4,5,6))? $type : 1;
        $this->_maxLength = intval($maxlength);
    }


    /** 前端入列
    * @param  Mixed   $data 數據
    * @return boolean
    */
    public function frontAdd($data=null){

        if($this->_type==3){ // 前端輸入限制
            return false;
        }

        if(isset($data) && !$this->isFull()){

            array_unshift($this->_queue, $data);

            $this->setAddNum(1);

            return true;
        }

        return false;

    }


    /** 前端出列
    * @return Array
    */
    public function frontRemove(){

        if($this->_type==2){ // 前端輸出限制
            return null;
        }

        if(!$this->checkRemove(1)){ // 檢查是否依賴輸入
            return null;
        }

        $data = null;

        if($this->getLength()>0){

            $data = array_shift($this->_queue);

            $this->setRemoveNum(1);

        }

        return $data;

    }


    /** 後端入列
    * @param  Mixed   $data 數據
    * @return boolean
    */
    public function rearAdd($data=null){

        if($this->_type==5){ // 後端輸入限制
            return false;
        }

        if(isset($data) && !$this->isFull()){

            array_push($this->_queue, $data);

            $this->setAddNum(2);

            return true;

        }

        return false;
    }


    /** 後端出列
    * @return Array
    */
    public function rearRemove(){

        if($this->_type==4){ // 後端輸出限制
            return null;
        }

        if(!$this->checkRemove(2)){ // 檢查是否依賴輸入
            return null;
        }

        $data = null;

        if($this->getLength()>0){

            $data = array_pop($this->_queue);

            $this->setRemoveNum(2);

        }

        return $data;

    }


    /** 清空對列
    * @return boolean
    */
    public function clear(){
        $this->_queue = array();
        $this->_frontNum = 0;
        $this->_rearNum = 0;
        return true;
    }


    /** 判斷對列是否已滿
    * @return boolean
    */
    public function isFull(){
        $bIsFull = false;
        if($this->_maxLength!=0 && $this->_maxLength==$this->getLength()){
            $bIsFull = true;
        }
        return $bIsFull;
    }


    /** 獲取當前對列長度
    * @return int
    */
    private function getLength(){
        return count($this->_queue);
    }


    /** 記錄入列,輸出依賴輸入時調用
    * @param int $endpoint 端點 1:front 2:rear
    */
    private function setAddNum($endpoint){
        if($this->_type==6){
            if($endpoint==1){
                $this->_frontNum ++;
            }else{
                $this->_rearNum ++;
            }
        }
    }


    /** 記錄出列,輸出依賴輸入時調用
    * @param int $endpoint 端點 1:front 2:rear
    */
    private function setRemoveNum($endpoint){
        if($this->_type==6){
            if($endpoint==1){
                $this->_frontNum --;
            }else{
                $this->_rearNum --;
            }
        }
    }


    /** 檢查是否輸出依賴輸入
    * @param int $endpoint 端點 1:front 2:rear
    */
    private function checkRemove($endpoint){
        if($this->_type==6){
            if($endpoint==1){
                return $this->_frontNum>0;
            }else{
                return $this->_rearNum>0;
            }
        }
        return true;
    }

} // class end

?>

demo.php數組

<?php

require "DEQue.class.php";

// 例子1

$obj = new DEQue(); // 先後端均可以輸入,無限長度

$obj->frontAdd('a'); // 前端入列
$obj->rearAdd('b');  // 後端入列
$obj->frontAdd('c'); // 前端入列
$obj->rearAdd('d');  // 後端入列

// 入列後數組應爲 cabd

$result = array();

$result[] = $obj->rearRemove(); // 後端出列
$result[] = $obj->rearRemove(); // 後端出列
$result[] = $obj->frontRemove(); // 前端出列
$result[] = $obj->frontRemove(); // 前端出列

print_r($result); // 出列順序應爲 dbca

// 例子2
$obj = new DEQue(3, 5); // 前端只能輸出,後端可輸入輸出,最大長度5

$insert = array();
$insert[] = $obj->rearAdd('a');
$insert[] = $obj->rearAdd('b');
$insert[] = $obj->frontAdd('c'); // 因前端只能輸出,所以這裏會返回false
$insert[] = $obj->rearAdd('d');
$insert[] = $obj->rearAdd('e');
$insert[] = $obj->rearAdd('f');
$insert[] = $obj->rearAdd('g'); // 超過長度,返回false

var_dump($insert);

// 例子3
$obj = new DEQue(6); // 輸出依賴輸入

$obj->frontAdd('a');
$obj->frontAdd('b');
$obj->frontAdd('c');
$obj->rearAdd('d');

$result = array();
$result[] = $obj->rearRemove();
$result[] = $obj->rearRemove();  // 由於輸出依賴輸入,這個會返回NULL
$result[] = $obj->frontRemove();
$result[] = $obj->frontRemove();
$result[] = $obj->frontRemove();

var_dump($result);

?>


源碼下載地址:點擊查看數據結構

相關文章
相關標籤/搜索