通过对stack和queue的学习,我们似乎觉得数据结构其实很简单。当然,这仅仅是开始。我们从顺序表、链表开始,到现在的栈、队列,其实都是在为以后做铺垫。在树和图的遍历算法中,可以看到栈和队列。这里,我们简单看一下栈和队列的一些实际应用。回文题假设有一段文字,我们要判断是不是“回文”(不是回文兄弟的文字)。您可以使用堆栈来解决这个问题。回文是指将正文一分为二后,前一段的内容与后一段的内容完全相同,只是顺序颠倒了。比如非常有名的:上海的自来水来自大海。上海自来,来自大海,这种两段式的结构构成了一句话的回文。又如一段偶数字符:abcddcba,也是回文。类似的问题其实很容易出现在一些简单的算法面试题中。相信很多朋友都已经看出端倪了。我们可以压栈的前半部分,然后一个一个弹出,继续下半部分。比较可以判断当前字符串是否为回文。不光说不练,还是用代码来实现吧。$string1='abcdedcba';$string2='abcdeedcba';$string3='abcdefcba';functiongetIsPlalindrome($string){if(gettype($string)!='string'){returnfalse;}$strlen=strlen($string);$mid=floor($strlen/2);$arr=[];如果($strlen<2){返回假;}//stackfor($i=0;$i<$mid;$i++){array_push($arr,$string[$i]);}$j=$mid;$i=$strlen%2==0?$中值:$中值+1;计数开始(;$i<$strlen;$i++){$v=$arr[$j-1];//获取栈顶元素if($v!=$string[$i]){returnfalse;}array_pop($arr);//弹出顶部元素$j--;}如果($arr){返回假;}返回真;}var_dump(getIsPlalindrome($string1));//bool(true)var_dump(getIsPlalindrome($string2));//bool(true)var_dump(getIsPlalindrome($string3));//bool(false)非常简单,只需使用array_push()和array_pop()执行顺序堆栈操作。唯一需要注意的是,对于字符长度奇偶数的不同,我们要取的中位数也会随之变化。回文算法比较简单。此外,简单的括号匹配、算术运算、中缀转后缀表达式等经常出现的问题,都是典型的栈类算法面试题。大家可以自行查找相关内容进行尝试。递归在讲递归之前,我们需要明确一件事,那就是:编程语言中的函数调用本质上都是栈调用。怎么理解这句话?我们在执行代码的时候,如果遇到一个函数,总是会先进入这个函数,运行完这个函数中的代码后,再回到原来的代码执行行,继续执行调用当前函数的代码。例如,下面的代码。functiontestA(){echo'Astart.',PHP_EOL;测试B();echo'Aend.',PHP_EOL;}functiontestB(){echo'Bstart.',PHP_EOL;echo'Bend.',PHP_EOL;}echo'Pstart.',PHP_EOL;testA();echo'Pend.',PHP_EOL;//Pstart.//Astart.//Bstart.//Bend.//Aend.//Pend.当前页面P运行到testA()函数时,进入testA()函数执行其内部代码,即P->A,然后testA()函数调用testB()函数,所以现在进入testB(),执行函数体中的代码,即P->A->B。当testB()的代码运行完毕,回到testA()继续执行testA()函数体的内容,最后回到页面P继续向下执行,即B->A->P.如果上面的描述你一次没看懂,请多看几遍,细细品味。这不就是一个栈调用过程吗!!这样看,在编程语言中,栈确实深入骨髓。因为只要你在开发代码,那么你就一定在用栈。而“递归”是一种比较典型的栈实现方式。函数递归($n){如果($n==0||$n==1){返回1;}$result=递归($n-1)*$n;返回$result;}echo递归(10),PHP_EOL;这是阶乘算法的简单递归实现。由于递归会建栈,所以我们在这段代码中首先计算的是栈底的n为1,从栈中返回1后,再次出栈就是1乘以2,然后继续弹出堆栈以将2乘以3,依此类推,直到计算出从1到10的阶乘结果。递归相关的面试题在我们面试中也很常见,所以一定要把握递归其实就是栈的一种形式,然后用栈的思想来解构整个递归调用过程。队列应用最后,我们来谈谈队列的一些实际应用。事实上,在代码层面,队列的好的例子并不多。比较常见的可能是两个队列合并出队(舞伴问题)或者两组队列一起出队。这种问题。您可以自行查找相关主题。相对来说,排队的算法题还是比较少的,包括在考研中,大部分都是作为选择、判断等题出现的。但是在实际应用中,队列现在是解决高并发问题的超级法宝,也是面试官评判你经验的重要内容。在实际项目开发中,队列最典型的作用之一就是秒杀问题。就像抢火车票、抢小米手机一样,一时间大量请求涌入。如果仅仅依靠服务器来处理,超高的并发不仅会给服务器带来很大的压力,还可能引发各种问题。只有在高并发场景下才会出现的问题,比如超卖、事务异常等(多个线程同时更新数据)而队列是解决这个问题的好手。通常我们使用的队列系统(redis、rabbitmq)都是基于内存的队列系统,其特点是存储非常快。前端(producer)产生的大量请求在后台脚本(consumer)中进行排队(enqueued),然后处理(dequeued)。前端只需要返回一个正在处理或排队的提示,等后台处理完成后,通知前端显示结果即可。这样在秒杀场景下,基本解决了高并发的问题。当然在真实环境中可能需要考虑更多的因素,但核心还是以队列的形式来解决这种瞬时高并发的业务功能。另外,队列还有一个重要的业务场景,就是发送通知、消息、邮件、短信等信息。因为队列可以解决的一些问题最大的特点就是需要生产者/消费者业务的解耦。通常我们在批量发送消息的时候,都会进行大规模的批量发送。这个时候我们只需要准备好消息内容以及对应的手机号和设备id,然后让系统在后台队列中慢慢发送消息即可,不需要我们前端等待消息发送完毕。这时候很多朋友看到了一点办法。在实际应用中,队列就是多线程的感觉。JS中的事件回调和CPU的碎片化时间轮询不就是队列的真正应用吗?还有设计模式中的“观察者模式”,它本身就是一种事件回调机制的编程范式,所以我们在它实现的很多功能中都能看到队列的影子。总结一下,栈和队列其实是我们在开发过程中每天都要接触的东西。你是否觉得自己的脑容量不够用?再想想,我们的栈和队列还有什么关系呢?其实你只需要掌握它们的两个本质:栈是后进先出(LIFO)或者先进后出(FILO),队列是先进先出(FIFO)).测试代码:https://github.com/zhangyue0503/Data-structure-and-algorithm/blob/master/3。Stacksandqueues/source/3.3stacksandqueues.php的应用参考资料:《数据结构》第二版,闫伟民《数据结构》第二版,陈越《数据结构高分笔记》2020年版,天琴考研各自媒体平台可搜索【硬核】专案经理]
