1. ホーム
  2. Web プログラミング
  3. PHP プログラミング
  4. phpのヒント

php の双方向キューの例

2022-01-14 06:54:53

1. 双方向キューは、キューとスタックの性質を併せ持つデータ構造です。

2. 双方向待ち行列の要素は両端からポップすることができ、その限定された挿入と削除の操作はテーブルの両端で実行されます。

双方向キューは、キューと似ていますが、どちらかの端で要素の追加や削除を行うことができます。

インスタンス

<?php
class DoubleQueue
{
    public $queue = array();
    /** (tail) inbound ***    public function addLast($value)
    {
        return array_push($this->queue,$value);
    }
    /** (tail) out of the queue **    public function removeLast()
    {
 
        return array_pop($this->queue);
 
    }
 
    /** (head) in the queue ** 
    public function addFirst($value)
 
    {
        return array_unshift($this->queue,$value);
 
    }
 
    /**(head) out of the queue**    public function removeFirst()
    {
        return array_shift($this->queue);
    }
    /* Empty the queue **    public function makeEmpty()
    {
        unset($this->queue);
    }
    /* Get the head of the column **    public function getFirst()
    {
        return reset($this->queue);
    }
    /* Get the end of the column **    public function getLast()
    {
        return end($this->queue);
    }
    /** Get length **    public function getLength()
    {
        return count($this->queue);
    }
}

インスタンスの拡張機能。

(deque, フルネーム double-ended queue) は、キューとスタックの性質を併せ持つデータ構造である。ダブルエンド型キューの要素は両端からポップすることができ、その修飾された挿入および削除操作はテーブルの両端で実行されます。

実際には、出力制限のある双方向キュー(一方の端点では挿入と削除を許し、他方の端点では 挿入のみを許す双方向キュー)や入力制限のある双方向キュー(一方の端点では挿入と削除を許し、他方の端点では 削除のみを許す双方向キュー)も存在しうる。もし、双方向キューが、一方の端点からの挿入と、その端点からの削除のみを許可するように制限されている場合、双方向キューは、スタックの底で互いに隣接する二つのスタックに形態変化します。

DEQue.class.phpのクラスファイルは以下の通りです。

<?php 
/** php two-way queue. Supports limited queue length, restricted input, restricted output, and output must be on the same end as the input 
* Date: 2014-04-30 
* Author: fdipzone 
* Ver: 1.0 
*Ver: 1.0 
* Func: 
* public frontAdd FrontIn 
* public frontRemove frontRemove 
* public rearAdd rearRemove 
* pulbic rearRemove rearRemove 
* public clear clears the pair of columns 
* public isFull Determine if the column is full 
* private getLength Get the length of the pair of columns 
* private setAddNum Record the incoming column, called when the output depends on the input 
* private setRemoveNum record the out column, called when the output depends on the input 
* private checkRemove Check if the output depends on the input 
*/ 
 
class DEQue{ // class start 
 
  private $_queue = array(); // pairs of columns 
  private $_maxLength = 0; // maximum length of the column, 0 means no limit 
  private $_type = 0; // column type 
  private $_frontNum = 0; // number of front inserts 
  private $_rearNum = 0; // the number of back-end insertions 
 
 
  /** Initialization 
  * @param $type Pair of column types 
  * 1:Both ends can input and output 
  * 2:front-end can only input, back-end can input and output 
  * 3:Front end can only output, back end can input and output 
  * 4:back-end can only input, front-end can input and output 
  * 5:Back end can only output, front end can input and output 
  * 6:Both ends can input and output, input at which end can only output from which end 
  * @param $maxlength The maximum length of the pair of columns 
  */ 
  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); 
  } 
 
 
  /** Front-end entry 
  * @param Mixed $data data 
  * @return boolean 
  */ 
  public function frontAdd($data=null){ 
 
    if($this->_type==3){ // front-end input limit 
      return false; 
    } 
 
    if(isset($data) && ! $this->isFull()){ 
 
      array_unshift($this->_queue, $data); 
 
      $this->setAddNum(1); 
 
      return true; 
    } 
    return false; 
  } 
 
  /** frontend out of the column 
  * @return Array 
  */ 
  public function frontRemove(){ 
 
    if($this->_type==2){ // frontEndOut restriction 
      return null; 
    } 
 
    if(! $this->checkRemove(1)){ // Check for input dependency 
      return null; 
    } 
 
    $data = null; 
 
    if($this->getLength()>0){ 
 
      $data = array_shift($this->_queue); 
 
      $this->setRemoveNum(1); 
    } 
    return $data; 
  } 
 
  /** Back-end incoming 
  * @param Mixed $data data 
  * @return boolean 
  */ 
  public function rearAdd($data=null){ 
 
    if($this->_type==5){ // backend input limit 
      return false; 
    } 
 
    if(isset($data) && ! $this->isFull()){ 
 
      array_push($this->_queue, $data); 
 
      $this->setAddNum(2); 
 
      return true; 
    } 
    return false; 
  } 
 
  /** Backend out of the column 
  * @return Array 
  */ 
  public function rearRemove(){ 
 
    if($this->_type==4){ // Back-end output limit 
      return null; 
    } 
 
    if(! $this->checkRemove(2)){ // Check for input dependency 
      return null; 
    } 
 
    $data = null; 
 
    if($this->getLength()>0){ 
 
      $data = array_pop($this->_queue); 
 
      $this->setRemoveNum(2); 
    } 
    return $data; 
  } 
 
  /** Clear the pair of columns 
  * @return boolean 
  */ 
  public function clear(){ 
    $this->_queue = array(); 
    $this->_frontNum = 0; 
    $this->_rearNum = 0; 
    return true; 
  } 
 
  /** Determine if the pair of columns is full 
  * @return boolean 
  */ 
  public function isFull(){ 
    $bIsFull = false; 
    if($this->_maxLength!=0 && $this->_maxLength==$this->getLength()){ 
      $bIsFull = true; 
    } 
    return $bIsFull; 
  } 
 
  /* Get the current pair of column lengths 
  * @return int 
  */ 
  private function getLength(){ 
    return count($this->_queue); 
  } 
 
  /* Called when the record is in the column, and the output depends on the input 
  * @param int $endpoint endpoint 1:front 2:rear 
  */ 
  private function setAddNum($endpoint){ 
    if($this->_type==6){ 
      if($endpoint==1){ 
        $this->_frontNum ++; 
      }else{ 
        $this->_rearNum ++; 
      } 
    } 
  } 
 
  /* Record out columns, called when output depends on input 
  * @param int $endpoint endpoint 1:front 2:rear 
  */ 
  private function setRemoveNum($endpoint){ 
    if($this->_type==6){ 
      if($endpoint==1){ 
        $this->_frontNum --; 
      }else{ 
        $this->_rearNum --; 
      } 
    } 
  } 
 
  /* Check if the output depends on the input 
  * @param int $endpoint 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"; 
 
// Example 1 
 
$obj = new DEQue(); // both front and back end can be entered, infinite length 
 
$obj->frontAdd('a'); // front-end entry 
$obj->rearAdd('b'); // back-end entry 
$obj->frontAdd('c'); // front in 
$obj->rearAdd('d'); // backend in 
 
// The array should be cabd after the entry 
 
$result = array(); 
 
$result[] = $obj->rearRemove(); // backend out 
$result[] = $obj->rearRemove(); // backend out 
$result[] = $obj->frontRemove(); // front end out 
$result[] = $obj->frontRemove(); // frontEndRemove() 
 
print_r($result); // The order of the columns should be dbca 
 
// Example 2 
$obj = n