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 相关文章推荐
js FLASH幻灯片字符串中有连接符&的处理方法
Mar 01 Javascript
文字不间断滚动(上下左右)实例代码
Apr 21 Javascript
深入理解javaScript中的事件驱动
May 21 Javascript
JS获取键盘上任意按键的值(实例代码)
Nov 12 Javascript
JavaScript作用域与作用域链深入解析
Dec 06 Javascript
gridview生成时如何去掉style属性中的border-collapse
Sep 30 Javascript
JS获取鼠标坐标位置实例分析
Jan 20 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
May 12 Javascript
JavaScript必知必会(六) delete in instanceof
Jun 08 Javascript
基于JSON数据格式详解
Aug 31 Javascript
详解使用vuex进行菜单管理
Dec 21 Javascript
JavaScript命名空间模式实例详解
Jun 20 Javascript
原生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
PHP 5.0对象模型深度探索之类的静态成员
2008/03/27 PHP
php中$_GET与$_POST过滤sql注入的方法
2014/11/03 PHP
PHP基于mssql扩展远程连接MSSQL的简单实现方法
2016/10/08 PHP
一个很酷的拖动层的js类,兼容IE及Firefox
2009/06/23 Javascript
javascript parseInt与Number函数的区别
2010/01/21 Javascript
JS保存、读取、换行、转Json报错处理方法
2013/06/14 Javascript
JavaScript定义类的几种方式总结
2014/01/06 Javascript
js如何打印object对象
2015/10/16 Javascript
React.js入门学习第一篇
2016/03/30 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
vue.js实现含搜索的多种复选框(附源码)
2017/03/23 Javascript
利用vscode编写vue的简单配置详解
2017/06/17 Javascript
JavaScript实现跟随滚动缓冲运动广告框
2017/07/15 Javascript
Nodejs模块载入运行原理
2018/02/23 NodeJs
vue实现在一个方法执行完后执行另一个方法的示例
2018/08/25 Javascript
Vue项目前后端联调(使用proxyTable实现跨域方式)
2020/07/18 Javascript
JS图片懒加载技术实现过程解析
2020/07/27 Javascript
原生JS实现九宫格抽奖
2020/09/13 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
Python交换变量
2008/09/06 Python
在Python的Flask框架下使用sqlalchemy库的简单教程
2015/04/09 Python
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
Python中set与frozenset方法和区别详解
2016/05/23 Python
python实现员工管理系统
2018/01/11 Python
python实现猜数游戏
2020/03/27 Python
Python基于当前时间批量创建文件
2020/05/07 Python
pycharm 实现光标快速移动到括号外或行尾的操作
2021/02/05 Python
美国在线咖啡、茶和餐厅供应商:LollicupStore
2018/05/04 全球购物
大学生村官心得体会范文
2014/01/04 职场文书
火锅店营销方案
2014/02/26 职场文书
人资专员岗位职责
2014/04/04 职场文书
小学生毕业评语
2014/12/26 职场文书
汉语拼音教学反思
2016/02/22 职场文书
2016见义勇为事迹材料汇总
2016/03/01 职场文书
python munch库的使用解析
2021/05/25 Python
win11系统中dhcp服务异常什么意思? Win11 DHCP服务异常修复方法
2022/04/08 数码科技