概念

Queue,队列,是一种先进先出(Fisrt In Fisrt Out , FIFO)的数据结构。

JS的实现

和栈类似的,在JS中没有专门的类实现这种数据结果,但是也是通过Array可以模拟。

  • 入列操作(enqueue):push();
  • 出列操作(dequeue):shift();

JS的EventLoop

JS引擎是单线程的,这大家都知道。但是明显我们的程序是有异步能力的。
所以这里涉及一个模型,是这样:
JS只执行任务队列里面的函数。在程序的最初阶段,我们的主流程其实本身就是一个函数,该函数在被执行的过程中,我们遇到了异步任务,setTimeout、网络请求之类的,这些任务的执行者可不是JS本事,JS是直接交给平台执行的,比如node或者浏览器。
当异步的任务被执行完成后,平台会把完成后的回调函数放在任务队列中,这个回调函数当然就是程序员在代码里面写的回调。
那么这些后续的任务(回调函数),自然会被JS引擎在后面的过程中从queue中dequeue出来并执行。
所以,下面这道最简单的题:

  1. setTimeout(() => {
  2. console.log('1')
  3. }, 0)
  4. console.log('2')

这个例子的打印顺序2、1,因为我们timeout中的函数的经历可不简单,是平台在执行完timeout之后,把这个函数放在任务队列中的,再由JS从任务队列中拿出来并执行的。

image.png
上图就描述了这个过程,这整个过程被称作,Event Loop。

BFS:广度优先遍历

BFS(Breadth First Search)
就是广度优先。其过程检验来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。
image.png
对于上面的例子来说,广度优先遍历的结果是:A, B, C, D, E, F, G, H, I (假设每层节点从左到右访问)。
广度优先遍历各个节点,需要使用到队列(Queue),queue的特点是先进先出,整个遍历过程如下:
首先将A节点插入队列中,queue(A);
将A节点弹出,同时将A的子节点B,C插入队列中,此时B在队列首,C在队列尾部,queue(B,C);
将B节点弹出,同时将B的子节点D,E插入队列中,此时C在队列首,E在队列尾部,queue(C,D,E);
将C节点弹出,同时将C的子节点F,G,H插入队列中,此时D在队列首,H在队列尾部,queue(D,E,F,G,H);
将D节点弹出,D没有子节点,此时E在队列首,H在队列尾部,queue(E,F,G,H)
将E节点弹出,将其子节点I插入,此时queue(F,G,H,I )
其实,这些节点都是没有子节点的,后面的步骤中就是依次把他们弹出队列,直到队列空空如也。