队列是一种特殊的线性表,它只允许在表的前端,可以称之为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;