JavaScript队列结构Queue实现过程解析


Posted in Javascript onMarch 07, 2020

一、队列简介

队列是是一种受限的线性表,特点为先进先出(FIFO:first in first out)。

受限之处在于它只允许在表的前端(front)进行删除操作;在表的后端(rear)进行插入操作;

JavaScript队列结构Queue实现过程解析

相当于排队买票,先来的先买票,后来的后买票。

JavaScript队列结构Queue实现过程解析

队列的应用:

打印队列:计算机打印多个文件的时候,需要排队打印;线程队列:当开启多线程时,当新开启的线程所需的资源不足时就先放入线程队列,等待CPU处理;

队列类的实现:

队列的实现和栈一样,有两种方案:

基于数组实现;基于链表实现;

队列的常见操作:

  • enqueue(element):向队列尾部添加一个(或多个)新的项;
  • dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素;
  • front():返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息与Stack类的peek方法非常类似);
  • isEmpty():如果队列中不包含任何元素,返回true,否则返回false;
  • size():返回队列包含的元素个数,与数组的length属性类似;
  • toString():将队列中的内容,转成字符串形式;

二、封装队列类

2.1.代码实现

// 基于数组封装队列类
  function Queue() {
  // 属性
   this.items = []
   
  // 方法
  // 1.enqueue():将元素加入到队列中
  Queue.prototype.enqueue = element => {
   this.items.push(element)
  }

  // 2.dequeue():从队列中删除前端元素
  Queue.prototype.dequeue = () => {
   return this.items.shift()
  }

  // 3.front():查看前端的元素
  Queue.prototype.front = () => {
   return this.items[0]
  }

  // 4.isEmpty:查看队列是否为空
  Queue.prototype.isEmpty = () => {
   return this.items.length == 0;
  }

  // 5.size():查看队列中元素的个数
  Queue.prototype.size = () => {
   return this.items.length
  }

  // 6.toString():将队列中元素以字符串形式输出
  Queue.prototype.toString = () => {
   let resultString = ''
    for (let i of this.items){
     resultString += i + ' '
    }
    return resultString
   }
  }

测试代码:

// 创建队列
  let queue = new Queue()

  // 将元素加入到队列中
  queue.enqueue('a')
  queue.enqueue('b')
  queue.enqueue('c')
  queue.enqueue('d')
  console.log(queue);                       //58

  // 从队列中删除元素
  queue.dequeue()
  console.log(queue);                       //62
  queue.dequeue()
  console.log(queue);                       //64

  //front
  console.log(queue.front());                   //67
  
  // 验证其他方法
  console.log(queue.isEmpty());                  //70
  console.log(queue.size());                   //71
  console.log(queue.toString());                 //72

测试结果:

JavaScript队列结构Queue实现过程解析

2.2.队列的应用

使用队列实现小游戏:击鼓传花,传入一组数据和设定的数字num,循环遍历数组内元素,遍历到的元素为指定数字num时将该元素删除,直至数组剩下一个元素。

代码实现:

// 队列应用:面试题:击鼓传花
  let passGame = (nameList, num) => {
   //1.创建队列结构
   let queue = new Queue()

   //2.将所有人依次加入队列
   // 这是ES6的for循环写法,i相当于nameList[i]
   for(let i of nameList){
    queue.enqueue(i)
   }
   

   // 3.开始数数
   while(queue.size() > 1){//队列中只剩1个人就停止数数
   // 不是num的时候,重新加入队列末尾
   // 是num的时候,将其从队列中删除
   // 3.1.num数字之前的人重新放入队列的末尾(把队列前面删除的加到队列最后)
   for(let i = 0; i< num-1; i++ ){
    queue.enqueue(queue.dequeue())
   }
   // 3.2.num对应这个人,直接从队列中删除
   /*
    思路是这样的,由于队列没有像数组一样的下标值不能直接取到某一元素,所以采用,把num前面的num-1个元素先删除后添加到队列末尾,这样第num个元素就排到了队列的最前面,可以直接使用dequeue方法进行删除
   */
   queue.dequeue()
   }

   //4.获取剩下的那个人
   console.log(queue.size());                  //104
   let endName = queue.front()
   console.log('最终剩下的人:' + endName);            //106  
   
   return nameList.indexOf(endName);
  }

  //5.测试击鼓传花
  let names = ['lily', 'lucy', 'Tom', 'Lilei', 'Tony']
  console.log(passGame(names, 3));                //113

测试结果:

JavaScript队列结构Queue实现过程解析

三、优先队列

优先级队列主要考虑的问题为:

每个元素不再只是一个数据,还包含数据的优先级;在添加数据过程中,根据优先级放入到正确位置;3.1.优先级队列的实现

代码实现:

// 封装优先级队列
  function PriorityQueue() {

   //内部类:在类里面再封装一个类;表示带优先级的数据
   function QueueElement(element, priority) {
    this.element = element;
    this.priority = priority;
   } 

   // 封装属性
   this.items = []

   // 1.实现按照优先级插入方法
   PriorityQueue.prototype.enqueue = (element, priority) => {
    // 1.1.创建QueueElement对象
    let queueElement = new QueueElement(element, priority)

    // 1.2.判断队列是否为空
    if(this.items.length == 0){
     this.items.push(queueElement)
    }else{
     // 定义一个变量记录是否成功添加了新元素
     let added = false
     for(let i of this.items){
      // 让新插入的元素与原有元素进行优先级比较(priority越小,优先级越大)
      if(queueElement.priority < i.priority){
       this.items.splice(i, 0, queueElement)
       added = true
       // 新元素已经找到插入位置了可以使用break停止循环
       break
      }
     }
     // 新元素没有成功插入,就把它放在队列的最前面
     if(!added){
      this.items.push(queueElement)
     }
    }
   }

   // 2.dequeue():从队列中删除前端元素
   PriorityQueue.prototype.dequeue = () => {
    return this.items.shift()
   }

   // 3.front():查看前端的元素
   PriorityQueue.prototype.front = () => {
    return this.items[0]
   }

   // 4.isEmpty():查看队列是否为空
   PriorityQueue.prototype.isEmpty = () => {
    return this.items.length == 0;
   }

   // 5.size():查看队列中元素的个数
   PriorityQueue.prototype.size = () => {
    return this.items.length
   }

   // 6.toString():以字符串形式输出队列中的元素
   PriorityQueue.prototype.toString = () => {
    let resultString = ''
     for (let i of this.items){
      resultString += i.element + '-' + i.priority + ' '
     }
     return resultString
    }
  }

测试代码:

// 测试代码
  let pq = new PriorityQueue();
  pq.enqueue('Tom',111);
  pq.enqueue('Hellen',200);
  pq.enqueue('Mary',30);
  pq.enqueue('Gogo',27);
  // 打印修改过后的优先队列对象
  console.log(pq);

测试结果:

JavaScript队列结构Queue实现过程解析

3.2.注意点

关于数组方法splice用法:

splice(1,0,'Tom'):表示在索引为1的元素前面插入元素'Tom‘(也可以理解为从索引为1的元素开始删除,删除0个元素,再在索引为1的元素前面添加元素'Tom');

splice(1,1,'Tom'):表示从索引为1的元素开始删除(包括索引为1的元素),共删除1个元素,并添加元素'Tom'。即把索引为1的元素替换为元素'Tom'。

数组的push方法在数组、栈和队列中的形式:

  • 数组:在数组[0,1,2]中,pop(3),结果为[0,1,2,3];
  • 栈:执行pop(0),pop(1),pop(2),pop(3),从栈底到栈顶的元素分别为:0,1,2,3;如果看成数组,可写为[0,1,2,3],但是索引为3的元素3其实是栈顶元素;所以说栈的push方法是向栈顶添加元素(但在数组的视角下为向数组尾部添加元素);
  • 队列:enqueue方法可以由数组的push方法实现,与数组相同,相当于在数组尾部添加元素。

可以这样想:栈结构是头朝下(索引值由下往上增大)的数组结构。

JavaScript队列结构Queue实现过程解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript实现DIV滚动自动滚动到底部的代码
Mar 01 Javascript
MultiSelect左右选择控件的设计与实现介绍
Jun 08 Javascript
jQuery实现dialog设置focus焦点的方法
Jun 10 Javascript
AngularJS入门教程之服务(Service)
Jul 27 Javascript
解决Jstree 选中父节点时被禁用的子节点也会选中的问题
Dec 27 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
ES10 特性的完整指南小结
Mar 04 Javascript
解决一个微信号同时支持多个环境网页授权问题
Aug 07 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
Aug 12 Javascript
在nuxt中使用路由重定向的实例
Nov 06 Javascript
jquery实现图片放大镜效果
Dec 23 jQuery
详解Vue的sync修饰符
May 15 Vue.js
原生JS实现萤火虫效果
Mar 07 #Javascript
JavaScript实现轮播图片完整代码
Mar 07 #Javascript
JS实现瀑布流效果
Mar 07 #Javascript
Vue中使用better-scroll实现轮播图组件
Mar 07 #Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 #Javascript
node创建Vue项目步骤详解
Mar 06 #Javascript
小程序跳转到的H5页面再跳转回跳小程序的方法
Mar 06 #Javascript
You might like
搜索和替换文件或目录的一个好类--很实用
2006/10/09 PHP
php获取QQ头像并显示的方法
2014/12/23 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
一段利用WSH获取登录时间的jscript代码
2008/05/11 Javascript
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
基于jquery的模态div层弹出效果
2010/08/21 Javascript
jQuery fancybox在ie浏览器下无法显示关闭按钮的解决办法
2016/02/19 Javascript
基于Jquery插件Uploadify实现实时显示进度条上传图片
2020/03/26 Javascript
js 截取或者替换字符串中的数字实现方法
2016/06/13 Javascript
js输出数据精确到小数点后n位代码
2016/07/02 Javascript
AngularJS基础 ng-class-odd 指令示例
2016/08/01 Javascript
AngularJS ng-mousedown 指令
2016/08/02 Javascript
关于jQuery中fade(),show()起始位置的一点小发现
2017/04/25 jQuery
angular中不同的组件间传值与通信的方法
2017/11/04 Javascript
JavaScript生成简单等差数列
2017/11/28 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
vue无限轮播插件代码实例
2019/05/10 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
简单实现节流函数和防抖函数过程解析
2019/10/08 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
JS实现炫酷轮播图
2020/11/15 Javascript
如何在VUE中使用vue-awesome-swiper
2021/01/04 Vue.js
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
在 Python 应用中使用 MongoDB的方法
2017/01/05 Python
Python利用全连接神经网络求解MNIST问题详解
2020/01/14 Python
canvas绘制图片drawImage使用方法
2020/09/15 HTML / CSS
韩国女装NO.1网店:STYLENANDA
2016/09/16 全球购物
DC Shoes官网:美国滑板鞋和服饰品牌
2017/09/03 全球购物
世界上最大的糖果店:Dylan’s Candy Bar
2017/11/07 全球购物
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
电子工程专业毕业生求职信
2014/03/14 职场文书
房屋买卖协议书范本
2014/09/27 职场文书
干部作风整顿个人剖析材料
2014/10/06 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
2015国庆节66周年演讲稿
2015/03/20 职场文书
毕业论文致谢范文
2015/05/14 职场文书