zoukankan      html  css  js  c++  java
  • 算法笔记-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();

    运行:

  • 相关阅读:
    MTK 官方 openwrt SDK 使用
    PF_RING packet overwrites
    pycares cffi
    libevent evbuffer bug
    浮点转字符串性能比较
    重写 libev 的 EV_WIN32_HANDLE_TO_FD
    thrift TNonblockingServer 使用
    accel-pptp 部署
    boost::asio 使用 libcurl
    蜂鸟A20开发板刷 cubietruck 的 SD 卡固件
  • 原文地址:https://www.cnblogs.com/rxbook/p/10341991.html
Copyright © 2011-2022 走看看