队列是一种特殊的线性表,它只允许在表的前端,可以称之为head,进行删除操作;而在表的后端,可以称之为end进行插入操作。队列和堆栈一样,是一种操作受限制的线性表,和堆栈不同之处在于:队列是遵循“先进先出”原则,而堆栈遵循的是“先进后出”原则。队列进行插入操作的端称为队尾,进行删除操作的称为队头,只允许在队尾进行插入操作,在队头进行删除操作。

本案例中有两个类:

  第一个是data类,用于实现数据的存放以及队列元素的入队出队情况;

  第二个是queue类,用于队列元素的一些入队出队操作。

队列中包含四个属性:

  head(队列的头部)

  end(队列的尾部)

  maxsize(队列的长度,即队列元素个数)

  queue(存放所有已入队队列元素的对象)

  队列的数据元素又称为队列元素,在队尾中插入一个元素称为入队,在队头删除一个元素称为出队

        //  end [data1] [data2] [data3] [data4] head
        //  |                                   |
        //  入队                                出队
<?php
    
    /**
     *  php队列算法
     * email:327907762@qq.com  
     **/
    
    /**
     * 数据类
     *
     * @author Administrator
     *        
     */
    class Data
    {
    
        /**
         * 存放数据
         *
         * @var unknown
         */
        private $data;
    
        /**
         * 记录数的状态
         *
         * @var unknown
         */
        private $dataStatus;
    
        /**
         * 是否打印数据状态
         *
         * @var string
         */
        private $isDebug = false;
    
        /**
         * 数据类的构造函数
         *
         * @param unknown $data            
         */
        function __construct($data)
        {
            $this->data = $data;
            
            $this->dataStatus = $this->data . " is init" . PHP_EOL;
            if ($this->isDebug) {
                echo $this->dataStatus;
            }
        }
    
        /**
         * 获取数据
         *
         * @return unknown
         */
        public function getData()
        {
            $this->dataStatus = $this->data . " is getted" . PHP_EOL;
            if ($this->isDebug) {
                echo $this->dataStatus;
            }
            return $this->data;
        }
    
        /**
         * 是否打印数据状态的访问器
         *
         * @param unknown $isDebug            
         */
        public function setIsDebug($isDebug)
        {
            $this->isDebug = $isDebug;
        }
    
        /**
         * 获取数据状态
         *
         * @return unknown
         */
        public function getDataStatus()
        {
            return $this->dataStatus;
        }
    
        /**
         * 析构函数
         */
        function __destruct()
        {
            $this->dataStatus = $this->data . " is out" . PHP_EOL;
            if ($this->isDebug) {
                echo $this->dataStatus;
            }
        }
    }
    
    /**
     * 队列类型用来实现队列的逻辑
     *
     * @author Administrator
     *        
     */
    class Queue
    {
    
        /**
         * 队列的头部数
         *
         * @var unknown
         */
        protected $head;
    
        /**
         * 队列的尾部数
         *
         * @var unknown
         */
        protected $end;
    
        /**
         * 记录队列的数组
         *
         * @var array
         */
        protected $queue = array(
            0 => '队尾'
        );
    
        /**
         * 队列的最大数
         *
         * @var unknown
         */
        protected $maxsize;
    
        private $queueErr;
    
        /**
         * 初始化类的时候要去初始化队列的长度
         *
         * @param unknown $init_size            
         */
        function __construct(int $init_size)
        {
            // 初始化队列头尾和数据最大长度
            $this->initQ($init_size);
        }
    
        /**
         * 初始化队列头尾和数据最大长度
         * 初始化队列时,生成一个队列,传入一个参数作为maxsize初始化队列把队尾rear设为0,
         * 队头front也设为0,此时queue中只有0号元素,并且rear和front都指向它。
         *
         * @param int $init_size            
         */
        private function initQ(int $init_size)
        {
            $this->head = 0;
            
            $this->end = 0;
            
            $this->maxsize = $init_size;
        }
    
        /**
         * 队列是不是已满
         *
         * @return bool|NULL
         */
        public function isFull(): ?bool
        {
            $this->queueErr = "queue is full , length is {$this->maxsize}";
            return ($this->head - $this->end) >= $this->maxsize;
        }
    
        /**
         * 队列是不是空
         *
         * @return bool|NULL
         */
        public function isEmpty(): ?bool
        {
            $this->queueErr = "queue is empty, head is {$this->head},end is {$this->end}";
            return ($this->end == $this->head);
        }
    
        /**
         * * 进入队列
         * 入队时,先需要判断队列是否已满(head-end == maxsize),
         * 如果已满不可在插入,如果未满则允许插入。插入时,head 自增,
         * 然后依次让队列所有元素向前移动一位(让出队尾位置以便插入新元素),
         * 然后生成新的data对象插入到队尾位置。
         * 队列的格式
         * end [data1] [data2] [data3] [data4] head
         * |                                   |
         * 入队                                出队
         *
         * @param Data $data            
         * @param callable $inSuccess            
         * @return bool|NULL
         */
        public function inQueue($data, callable $inCallBack = null): ?bool
        {
            $inStatus = false;
            
            // 入队时,先需要判断队列是否已满(head-end == maxsize)
            if ($this->isFull()) {
                // 处理一个出队的成功回调
                $inData = new Data($this->queueErr);
                $inStatus = false;
            } else {
                // 开始入队列,head 自增
                $this->head ++;
                // 然后依次让队列所有元素向前移动一位(让出队尾位置以便插入新元素)
                for ($i = $this->head; $i > $this->end; $i --) {
                    if ($this->queue[$i]) {
                        unset($this->queue[$i]);
                    }
                    $this->queue[$i] = $this->queue[$i - 1];
                }
                // 然后生成新的data对象插入到队尾位置。
                $inData = new Data($data);
                $this->queue[$this->end + 1] = $inData;
                
                $inStatus = true;
            }
            
            // 处理一个入队的回调
            if (! empty($inCallBack) && $inCallBack instanceof Closure) {
                call_user_func($inCallBack, $inStatus, $inData);
            }
            
            return $inStatus;
        }
    
        /**
         * 出队函数
         * 出队时,判断队列是否为空(head == end),
         * 如果为空时,无法出队。如果不为空时,
         * 删除head指向的对象,并且head自减,完成出队。
         *
         * @param callable $outSuccess            
         * @return bool|NULL
         */
        public function outQueue(callable $outCallBack = null): ?bool
        {
            $outStatus = false;
            // 出队时,判断队列是否为空(head == end),
            if ($this->isEmpty()) {
                $outdata = new Data($this->queueErr);
                $outStatus = false;
            } else {
                // 临时寄存出队数据然后返给回调函数
                $outdata = $this->queue[$this->head];
                
                // 删除head指向的对象
                unset($this->queue[$this->head]);
                // 并且head自减,完成出队
                $this->head --;
                $outStatus = true;
            }
            
            // 处理一个出队的回调
            if (! empty($outCallBack) && $outCallBack instanceof Closure) {
                call_user_func($outCallBack, $outStatus, $outdata);
            }
            
            return $outStatus;
        }
    
        /**
         * 获取队首数据
         *
         * @return Data
         */
        public function getHeadData(): Data
        {
            return $this->queue[$this->head]->getData();
        }
    
        /**
         * 返回队列错误
         *
         * @return string|NULL
         */
        function getQueueErr(): ?string
        {
            return $this->queueErr;
        }
    }
    
    $queue = new Queue(3);
    
    $queue->inQueue("zhang san", function (bool $inStatus, Data $indata) {
        // echo $indata->getDataStatus();
        if ($inStatus) {
            echo $indata->getData() . " in queue" . PHP_EOL;
        } else {
            echo $indata->getData() . PHP_EOL;
        }
    });
    
    $queue->outQueue(function (bool $outStatus, Data $outdata) {
        if ($outStatus) {
            echo $outdata->getData() . " out queue" . PHP_EOL;
        } else {
            echo $outdata->getData() . PHP_EOL;
        }
    });
    
    $queue->inQueue("miaomiao", function (bool $inStatus, Data $indata) {
        // echo $indata->getDataStatus();
        if ($inStatus) {
            echo $indata->getData() . " in queue" . PHP_EOL;
        } else {
            echo $indata->getData() . PHP_EOL;
        }
    });
    $queue->inQueue("qwq1", function (bool $inStatus, Data $indata) {
        // echo $indata->getDataStatus();
        if ($inStatus) {
            echo $indata->getData() . " in queue" . PHP_EOL;
        } else {
            echo $indata->getData() . PHP_EOL;
        }
    });
    
    $queue->inQueue("qwq2", function (bool $inStatus, Data $indata) {
        // echo $indata->getDataStatus();
        if ($inStatus) {
            echo $indata->getData() . " in queue" . PHP_EOL;
        } else {
            echo $indata->getData() . PHP_EOL;
        }
    });
    $queue->inQueue("qwq3", function (bool $inStatus, Data $indata) {
        // echo $indata->getDataStatus();
        if ($inStatus) {
            echo $indata->getData() . " in queue" . PHP_EOL;
        } else {
            echo $indata->getData() . PHP_EOL;
        }
    });
    // echo $queue->getQueueErr() . PHP_EOL;
    
    $queue->outQueue(function (bool $outStatus, Data $outData) {
        if ($outStatus) {
            echo $outData->getData() . " out queue" . PHP_EOL;
        } else {
            echo $outData->getData() . PHP_EOL;
        }
    });
    $queue->outQueue(function (bool $outStatus, Data $outData) {
        if ($outStatus) {
            echo $outData->getData() . " out queue" . PHP_EOL;
        } else {
            echo $outData->getData() . PHP_EOL;
        }
    });
    $queue->outQueue(function (bool $outStatus, Data $outData) {
        if ($outStatus) {
            echo $outData->getData() . " out queue" . PHP_EOL;
        } else {
            echo $outData->getData() . PHP_EOL;
        }
    });
    $queue->outQueue(function (bool $outStatus, Data $outData) {
        if ($outStatus) {
            echo $outData->getData() . " out queue" . PHP_EOL;
        } else {
            echo $outData->getData() . PHP_EOL;
        }
    });
    //echo $queue->getQueueErr() . PHP_EOL;

QQ截图20190827101122.png

最后修改:2019 年 08 月 27 日
如果觉得我的文章对你有用,请随意赞赏