算法笔记-PHP实现队列的操作

【队列】先进者先出,这就是典型的“队列”。
        最基本的两个操作:入队enqueue(),放一个数据到队列尾部;出队dequeue(),从队列头部取一个元素。队列可以用数组或者链表实现,用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。
        队列需要两个指针:一个是 head 指针,指向队头;一个是 tail 指针,指向队尾。        
        在数组实现队列的时候,会有数据搬移操作,要想解决数据搬移的问题,我们就需要像环一样的 循环队列
         阻塞队列就是在队列为空的时候,从队头取数据会被阻塞,因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后在返回。
        在多线程的情况下,会有多个线程同时操作队列,这时就会存在线程安全问题。能够有效解决线程安全问题的队列就称为 并发队列
        基于链表的实现方式,可以实现一个支持无限排队的无界队列(unbounded queue),但是可能会导致过多的请求排队等待,请求处理的响应时间过长。所以,针对响应时间比较敏感的系统,基于链表实现的无限排队的线程池是不合适的。
        而基于数组实现的有界队列(bounded queue),队列的大小有限,所以线程池中排队的请求超过队列大小时,接下来的请求就会被拒绝,这种方式对响应时间敏感的系统来说,就相对更加合理。不过,设置一个合理的队列大小,也是非常有讲究的。队列太大导致等待的请求太多,队列太小会导致无法充分利用系统资源、发挥最大性能。
        实际上,对于大部分 资源有限的场景,当没有空闲资源时,基本上都可以通过“队列”这种数据结构来实现请求排队。 
 
<?php

/**
 * 队列 链表实现
 *
 * Class QueueOnLinkedList
 */
class QueueOnLinkedList
{
    /**
     * 队列头节点
     *
     * @var SingleLinkedListNode
     */
    public $head;

    /**
     * 队列尾节点
     *
     * @var null
     */
    public $tail;

    /**
     * 队列长度
     *
     * @var int
     */
    public $length;

    /**
     * QueueOnLinkedList constructor.
     */
    public function __construct()
    {
        $this->head = new SingleLinkedListNode();
        $this->tail = $this->head;

        $this->length = 0;
    }

    /**
     * 入队
     *
     * @param $data
     */
    public function enqueue($data)
    {
        $newNode = new SingleLinkedListNode();
        $newNode->data = $data;

        $this->tail->next = $newNode;
        $this->tail = $newNode;

        $this->length++;
    }

    /**
     * 出队
     *
     * @return SingleLinkedListNode|bool|null
     */
    public function dequeue()
    {
        if (0 == $this->length) {
            return false;
        }

        $node = $this->head->next;
        $this->head->next = $this->head->next->next;

        $this->length--;

        return $node;
    }

    /**
     * 获取队列长度
     *
     * @return int
     */
    public function getLength()
    {
        return $this->length;
    }

    /**
     * 打印队列
     */
    public function printSelf()
    {
        if (0 == $this->length) {
            echo 'empty queue' . PHP_EOL;
            return;
        }

        echo 'head.next -> ';
        $curNode = $this->head;
        while ($curNode->next) {
            echo $curNode->next->data . ' -> ';

            $curNode = $curNode->next;
        }
        echo 'NULL' . PHP_EOL;
    }
}

调用:

<?php
$queue = new QueueOnLinkedList();
$queue->enqueue(1);
$queue->enqueue(2);
$queue->enqueue(3);
$queue->enqueue(4);
$queue->enqueue(5);
$queue->printSelf();
var_dump($queue->getLength());

$queue->dequeue();
$queue->printSelf();
$queue->dequeue();
$queue->dequeue();
$queue->dequeue();
$queue->printSelf();

$queue->dequeue();
$queue->printSelf();

运行:

猜你喜欢

转载自www.cnblogs.com/kccdzz/p/10341991.html