广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >php中队列的示例分析
  • 747
分享到

php中队列的示例分析

2023-06-20 17:06:09 747人浏览 薄情痞子
摘要

小编给大家分享一下PHP中队列的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是队列?相对于栈来说,队列是一种先进先出(FIFO)的顺序逻辑结构。什么

小编给大家分享一下PHP中队列的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

什么是队列?

相对于栈来说,队列是一种先进先出(FIFO)的顺序逻辑结构。什么叫先进先出呢?就和我们的排队一样,当我们去银行或者医院的时候,总是要在门口取一个号,这个号是按顺序叫的。先来的人就可以先办业务或者看病,这就是一个典型的队列。同理,日常的排队就是一个标准的队列模式。

如果有插队的,在有正当理由的情况下,我们可以认为它的优先级更高,这是队列中元素的一种特殊形式。就像我们会在等地铁或者公交的时候让孕妇优先,在排队买火车票的时候也有军人的优先窗口。不过,这个并不在我们这次的讨论范围之内。

在公交站排队时,排第一个的当然可以第一个上车,然后依次。这时,你来到了公交站,那么你只能排到最后一位。这个就是队列的具体表现形式。

同样,和栈一样,也有一些名词我们需要了解。当你来到公交站并排到最后一位时,这个操作叫作“入队”。当公交车进站后,第一位乘客上车,这个操作叫做“出队”。第一位乘客所处的位置叫做“队头”,你做为当前队列的最后一位乘客,你的位置就叫做“队尾”。回到代码逻辑上面来看,也就是说队列是从“队尾”“入队”,从“队头”“出队”。

顺序队列

OK,我们还是直接从来代码来看,首先看到的依然是顺序队的实现。

class SqQueue{    public $data;    public $front;    public $rear;}

既然是顺序队,我们依然还是用一个数组 data 来表示队内的元素。然后定义两个指针 front 和 rear 来表示队头和队尾。因为是顺序队,所以这里的指针其实也就是保存的是数组的下标。接下来的操作其实就非常的简单了,“入队”时 rear++ ,“出队”时 front++ 。

function InitSqQueue(){    $queue = new SqQueue();    $queue->data = [];    $queue->front = 0;    $queue->rear = 0;    return $queue;}function EnSqQueue(SqQueue &$queue, $e){    $queue->data[$queue->rear] = $e;    $queue->rear ++;}function DeSqQueue(SqQueue &$queue){    // 队列为空    if($queue->front == $queue->rear){        return false;    }    $e = $queue->data[$queue->front];    $queue->front++;    return $e;}$q = InitSqQueue();EnSqQueue($q, 'A');EnSqQueue($q, 'B');print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => A//             [1] => B//         )//     [front] => 0//     [rear] => 2// )

是不是感觉学过了栈之后,队列也很好理解了。初始化队列时,就是让队头和队尾指针都是 0 下标的记录就可以了。入队的时候让队尾增加,在这段代码中,我们入队了两个元素,打印出来的顺序队列内容就如注释所示。

EnSqQueue($q, 'C');EnSqQueue($q, 'D');EnSqQueue($q, 'E');print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => A//             [1] => B//             [2] => C//             [3] => D//             [4] => E//         )//     [front] => 0//     [rear] => 5// )echo DeSqQueue($q), php_EOL; // Aecho DeSqQueue($q), PHP_EOL; // Becho DeSqQueue($q), PHP_EOL; // Cecho DeSqQueue($q), PHP_EOL; // Decho DeSqQueue($q), PHP_EOL; // Eecho DeSqQueue($q), PHP_EOL; // print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => A//             [1] => B//             [2] => C//             [3] => D//             [4] => E //         )//     [front] => 5//     [rear] => 5// )

出队的时候,就让 front 进行加 1 操作。不过,在出队的时候还需要判断数组中的元素是否全部出队了,在这里,我们只用了一个非常简单的判断条件,那就是 front 和 rear 是否相等来判断队列是否空了。大家可以通过一个图示来辅助对代码的理解。

php中队列的示例分析

循环队列

相信已经有不少同学看出来了。队列操作只是修改队头和队尾的指针记录,但是数组会一直增加,这样如果一直增加的话,就会导致这一个数组占满内存,这肯定不是一个好的队列实现。其实,在 C 语言中,数组就是要给一个固定的长度的。而 PHP 中的数组更像是一个 Hash 结构,所以它是可以无限增长的,并不需要我们在一开始定义一个具体的数组长度。

这也是 PHP 的方便之处,不过如果我们不想浪费内存空间的话,应该怎么办呢?就像在 C 语言中一样,我们在 PHP 中也为数组指定一个长度,并且使用非常经典的“循环队列”来解决队列数组的存储问题。就像下图所示:

php中队列的示例分析

其实意思就是,在有限的数组空间范围内,当我们达到数组的最大值时,将新的数据保存回之前的下标位置。比如图中我们有 6 个元素,当前队头在 2 下标,队尾在 5 下标。如果我们入队一个元素,队尾移动到 6 下标。再添加一个元素的话,队尾移动回 0 下标,如果继续添加的话,当队尾下标等于队头下标减 1 的时候,我们就认为这个队列已经满了,不能再增加元素了。

同理,出队操作的时候我们也是循环地操作队头元素,当队头元素到 6 的下标后,继续出队的话,也会回到 0 下标的位置继续出队。当队头和队尾相等时,当前的队列也可以判定为空队列了。

由此,我们可以看出,循环队列相比普通的线性队列来说,多了一个队满的状态。我们还是直接从代码中来看看这个队满的条件是如何判断的。

define('MAX_QUEUE_LENGTH', 6);function EnSqQueueLoop(SqQueue &$queue, $e){    // 判断队列是否满了    if(($queue->rear + 1) % MAX_QUEUE_LENGTH == $queue->front){        return false;    }    $queue->data[$queue->rear] = $e;    $queue->rear = ($queue->rear + 1) % MAX_QUEUE_LENGTH; // 改成循环下标}function DeSqQueueLoop(SqQueue &$queue){    // 队列为空    if($queue->front == $queue->rear){        return false;    }    $e = $queue->data[$queue->front];    $queue->front = ($queue->front + 1) % MAX_QUEUE_LENGTH; // 改成循环下标    return $e;}$q = InitSqQueue();EnSqQueueLoop($q, 'A');EnSqQueueLoop($q, 'B');EnSqQueueLoop($q, 'C');EnSqQueueLoop($q, 'D');EnSqQueueLoop($q, 'E');EnSqQueueLoop($q, 'F');print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => A//             [1] => B//             [2] => C//             [3] => D//             [4] => E//             [5] =>   // 尾//         )//     [front] => 0//     [rear] => 5// )echo DeSqQueueLoop($q), PHP_EOL;echo DeSqQueueLoop($q), PHP_EOL;print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => A//             [1] => B//             [2] => C // 头//             [3] => D//             [4] => E//             [5] =>   // 尾//         )//     [front] => 2//     [rear] => 5// )EnSqQueueLoop($q, 'F');EnSqQueueLoop($q, 'G');EnSqQueueLoop($q, 'H');print_r($q);// SqQueue Object// (//     [data] => Array//         (//             [0] => G//             [1] => B // 尾//             [2] => C // 头//             [3] => D//             [4] => E//             [5] => F//         )//     [front] => 2//     [rear] => 1// )

出、入队的下标移动以及队满的判断,都是以 (queue->rear + 1) % MAX_QUEUE_LENGTH 这个形式进行的。根据队列长度的取模来获取当前的循环下标,是不是非常地巧妙。不得不感慨先人的智慧呀!当然,这也是基本的数学原理哦,所以,学习数据结构还是要复习一下数学相关的知识哦!

链式队列

顺序队列有没有看懵?没关系,队列的链式结构其实相比顺序结构还要简单一些,因为它真的只需要操作队头和队尾的指针而已,别的真的就不太需要考虑了。而且这个指针就是真的指向具体对象的指针了。

class LinkQueuenode{    public $data;    public $next;}class LinkQueue{    public $first; // 队头指针    public $rear; // 队尾指针}

这里我们需要两个基本的物理结构。一个是节点 Node ,一个是队列对象,节点对象就是一个正常的链表结构,没啥特别的。而队列对象里面就更简单了,一个属性是队头指针,一个属性是队尾指针。

function InitLinkQueue(){    $node = new LinkQueueNode();    $node->next = NULL;    $queue = new LinkQueue();    $queue->first = $node;    $queue->rear = $node;    return $queue;}function EnLinkQueue(LinkQueue &$queue, $e){    $node = new LinkQueueNode();    $node->data = $e;    $node->next = NULL;    $queue->rear->next = $node;    $queue->rear = $node;}function DeLinkQueue(LinkQueue &$queue){    if($queue->front == $queue->rear){        return false;    }    $node = $queue->first->next;    $v = $node->data;    $queue->first->next = $node->next;    if($queue->rear == $node){        $queue->rear = $queue->first;    }    return $v;}$q = InitLinkQueue();EnLinkQueue($q, 'A');EnLinkQueue($q, 'B');EnLinkQueue($q, 'C');EnLinkQueue($q, 'D');EnLinkQueue($q, 'E');print_r($q);// LinkQueue Object// (//     [first] => LinkQueueNode Object//         (//             [data] => //             [next] => LinkQueueNode Object//                 (//                     [data] => A//                     [next] => LinkQueueNode Object//                         (//                             [data] => B//                             [next] => LinkQueueNode Object//                                 (//                                     [data] => C//                                     [next] => LinkQueueNode Object//                                         (//                                             [data] => D//                                             [next] => LinkQueueNode Object//                                                 (//                                                     [data] => E//                                                     [next] => //                                                 )//                                         )//                                 )//                         )//                 )//         )//     [rear] => LinkQueueNode Object//         (//             [data] => E//             [next] => //         )// )echo DeLinkQueue($q), PHP_EOL; // Aecho DeLinkQueue($q), PHP_EOL; // BEnLinkQueue($q, 'F');print_r($q);// LinkQueue Object// (//     [first] => LinkQueueNode Object//         (//             [data] => //             [next] => LinkQueueNode Object//                 (//                     [data] => C//                     [next] => LinkQueueNode Object//                         (//                             [data] => D//                             [next] => LinkQueueNode Object//                                 (//                                     [data] => E//                                     [next] => LinkQueueNode Object//                                         (//                                             [data] => F//                                             [next] => //                                         )//                                 )//                         )//                 )//         )//     [rear] => LinkQueueNode Object//         (//             [data] => F//             [next] => //         )// )

出、入队的代码函数和测试代码就一并给出了,是不是非常的简单。初始的队头元素依然是一个空节点做为起始节点。然后入队的时候,让 rear 等于新创建的这个节点,并在链表中建立链式关系。出队的时候也是同样的让 first 变成当前这个 first 的下一跳节点,也就是 first->next 就可以了。判断队空的条件也是简单的变成了队头和队尾指针是否相等就可以了。链队相比顺序队其实是简单了一些,不过同样的,next 这个东西容易让人头晕,硬记下来就可以了。大家还是可以结合图示来学习:

php中队列的示例分析

PHP 为我们提供的数组队列操作

最后,就和栈一样,PHP 代码中也为我们提供了一个可以用于队列操作的函数。

$sqQueueList = [];array_push($sqQueueList, 'a');array_push($sqQueueList, 'b');array_push($sqQueueList, 'c');print_r($sqQueueList);// Array// (//     [0] => a//     [1] => b//     [2] => c// )array_shift($sqQueueList);print_r($sqQueueList);// Array// (//     [0] => b//     [1] => c// )

array_shift() 函数就是弹出数组中最前面的那个元素。请注意,这里元素的下标也跟着变动了,如果我们是 unset() 掉数组的 0 下标元素的话,b 和 c 的下标依然还会是 1 和 2 。而 array_shift() 则会重新整理数组,让其下标依然有序。

unset($sqQueueList[0]);print_r($sqQueueList);// Array// (//     [1] => c// )

以上是“php中队列的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网PHP编程频道!

--结束END--

本文标题: php中队列的示例分析

本文链接: https://www.lsjlt.com/news/298728.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • php中队列的示例分析
    小编给大家分享一下php中队列的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是队列?相对于栈来说,队列是一种先进先出(FIFO)的顺序逻辑结构。什么...
    99+
    2023-06-20
  • C语言中队列的示例分析
    这篇文章将为大家详细讲解有关C语言中队列的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、队列(Queue)0x00 队列的概念 概念:① 队列只允许在一端进行插入数据操作,在另一端进...
    99+
    2023-06-29
  • Oracle高级队列的示例分析
    小编给大家分享一下Oracle高级队列的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Oracle高级队列(Advanc...
    99+
    2022-10-18
  • php双向队列的实例分析
    php双向队列的实例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。双向队列是指一种具有队列和栈的性质的数据结构。双向队列中的元素可以从两端弹出,其限定插入和...
    99+
    2023-06-25
  • C++中Queue队列类模版的示例分析
    这篇文章主要介绍C++中Queue队列类模版的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.队列的介绍队列的定义队列(Queue)是一种线性存储结构。它有以下几个特点:按照"先进先出(FIFO,...
    99+
    2023-06-29
  • JavaScript中数组、栈与队列的示例分析
    这篇文章主要介绍了JavaScript中数组、栈与队列的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。...
    99+
    2022-10-19
  • python中队列基本操作和多线程队列的示例分析
    这篇文章给大家分享的是有关python中队列基本操作和多线程队列的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、队列基本操作from queue import Queue...
    99+
    2023-06-29
  • Linux中多队列网卡硬件的示例分析
    小编给大家分享一下Linux中多队列网卡硬件的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!多队列网卡是一种技术,最初是用来解决网络IO QoS ...
    99+
    2023-06-12
  • Python中线程安全队列Queue的示例分析
    小编给大家分享一下Python中线程安全队列Queue的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、什么是队列?像排队一样,从头到尾排成一排,还可以有人继续往后排队,这就是队列。这里学委想说的是Queue这个...
    99+
    2023-06-29
  • Python的队列实例分析
    这篇“Python的队列实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python的队列实例分析”文章吧。模拟打印机...
    99+
    2023-06-29
  • laravel源码分析队列Queue方法示例
    目录前言队列任务的创建队列任务的分发前言 队列 (Queue) 是 laravel 中比较常用的一个功能,队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求...
    99+
    2022-11-13
  • JavaScript数据结构之优先队列与循环队列的示例分析
    这篇文章将为大家详细讲解有关JavaScript数据结构之优先队列与循环队列的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:优先队列实现一个优先队列:设...
    99+
    2022-10-19
  • Redis和队列的案例分析
    这篇文章给大家分享的是有关Redis和队列的案例分析的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。概要Redis不仅可作为缓存服务器,还可用作消息队列。它的列表类型天生支持用作消...
    99+
    2022-10-18
  • JavaScript单线程和任务队列的示例分析
    这篇文章给大家分享的是有关JavaScript单线程和任务队列的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、JavaScript为什么设计为单线程?JavaScri...
    99+
    2022-10-19
  • java并发中DelayQueue延迟队列原理的示例分析
    这篇文章给大家分享的是有关java并发中DelayQueue延迟队列原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。介绍DelayQueue队列是一个延迟队列,DelayQueue中存放的元素必须实现...
    99+
    2023-06-15
  • Java的栈和队列实例分析
    这篇文章主要讲解了“Java的栈和队列实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java的栈和队列实例分析”吧!栈package com.yuzhenc.collect...
    99+
    2023-06-29
  • PHP中session反序列化的示例分析
    小编给大家分享一下PHP中session反序列化的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!session反序列化的漏洞是由三种不同的反序列化引擎所产生的的漏洞其中session.serialize_handl...
    99+
    2023-06-29
  • Javascript队列方法实例分析
    这篇文章主要介绍“Javascript队列方法实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript队列方法实例分析”文章能帮助大家解决问题。J...
    99+
    2022-10-19
  • 消息队列RabbitMQ入门与PHP实例分析
    本篇内容主要讲解“消息队列RabbitMQ入门与PHP实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“消息队列RabbitMQ入门与PHP实例分析”吧!消息队列介绍以及消息队列应用场景Ra...
    99+
    2023-06-30
  • Java redisTemplate阻塞式处理消息队列的示例分析
    这篇文章主要介绍Java redisTemplate阻塞式处理消息队列的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Redis 消息队列redis五种数据结构队列生产者package c...
    99+
    2023-06-21
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作