JavaScript数据结构与算法之队列原理与用法实例详解


Posted in Javascript onNovember 22, 2017

本文实例讲述了JavaScript数据结构与算法之队列原理与用法。分享给大家供大家参考,具体如下:

队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素。队列用于存储按顺序排列的数据,先进先出,这点和栈不一样(后入先出)。在栈中,最后入栈的元素反而被优先处理。我们现在可以把队列想象对我们去餐馆吃饭的情景,很多人排队吃饭,排在最前面的人先打饭。新来的人只能在后面排队。直到轮到他们为止。

一:对队列的操作

队列有2种主要的操作,向队尾中插入新元素enqueue()方法和删除队列中的队首的元素的dequeue()方法,另外我们还有一个读取队头的元素,这个方法我们可以叫front()方法。该方法返回队头元素等等方法。

看到如上描述,我们很多人可能会想到数组,数组里面也有2个方法和上面的方法功能类似,数组中push()方法也是往数组后面加入新元素,数组中shift()方法则可以删除数组里面的第一个元素。如下代码:

var arrs = [];
arrs.push("a");
arrs.push("b");
console.log(arrs); // ["a","b"];
arrs.shift();
console.log(arrs); // ['b'];

下面我们可以使用上面的数组中的push()shift()的2个方法来封装我们的队列Queue类;

1.  我们可以先定义一个构造函数Queue类,如下:

function Queue() {
  this.dataStore = [];
}

如上:this.dataStore = []; 空数组时存储队列中所有的元素的。

2. 向队尾中添加一个元素方法如下:

function enqueue(element) {
   this.dataStore.push(element);
}

3. 删除队首的元素如下:

function dequeue() {
  return this.dataStore.shift()
}

4. 读取队首的元素如下:

function front() {
  return this.dataStore[0];
}

5. 读取队尾的元素如下:

function back() {
  return this.dataStore[this.dataStore.length - 1];
}

6. 显示队列中的所有元素

function toString() {
  var retStr = "";
  for(var i = 0; i < this.dataStore.length; ++i) {
    retStr += this.dataStore[i] + "\n";
  }
  return retStr;
}

7. 判断队列是否为空如下:

function empty(){
  if(this.dataStore.length == 0) {
    return true;
  }else {
    return false;
  }
}

下面是完整的JS代码如下:

function Queue() {
  this.dataStore = [];
}
Queue.prototype = {
  // 向队尾添加一个元素
  enqueue: function(element) {
    this.dataStore.push(element);
  },
  // 删除队首的元素
  dequeue: function(){
    return this.dataStore.shift();
  },
  // 读取队首的元素
  front: function(){
    return this.dataStore[0];
  },
  // 读取队尾的元素
  back: function(){
    return this.dataStore[this.dataStore.length - 1];
  },
  // 显示队列内的所有元素
  toString: function(){
    var retStr = "";
    for(var i = 0; i < this.dataStore.length; ++i) {
      retStr += this.dataStore[i] + "\n";
    }
    return retStr;
  },
  // 判断队列是否为空
  empty: function(){
    if(this.dataStore.length == 0) {
      return true;
    }else {
      return false;
    }
  }
};

我们现在可以对以上代码测试下:如下:

var q = new Queue();
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
console.log(q.toString()); // a b c
q.dequeue();
console.log(q.toString()); // b c
console.log("Front of queue:" +q.front()); // b
console.log("Back of queue:" +q.back()); // c

二:使用队列对数据进行排序

比如对于 0 ~ 99 的数字进行排序,原理是:先对个位上的数字进行排序一次,然后对十位上的数字再进行排序一次。每个数字根据对应位上的数值被分在不同的盒子里面,然后对于个位上的数字采用除余数的方法,对于10位上的数字采用除法的方法,那么这种排序叫做 “基数排序”. 但是它不是最快的排序方法,但是它描述了一些有趣的队列使用方法。

比如如下数组:

var nums = ["50","12","95","7","90","3","74","81","91","72"];

1. 经过基数排序--个位排序后,数字被分配在不同的盒子里面。(在JS里面,我们可以分配在不同的队列Queue实例类里面)。如下

queues[0] = 50 或者 90
queues[1] = 81 或者 91
queues[2] = 12 或者 72
queues[3] = 3
queues[4] = 74
queues[5] = 95
queues[6] 
queues[7] = 7
queues[8]
queues[9]

根据盒子的顺序,对数字第一次个位排序后结果如下:

nums = [50,90,81,91,12,72,3,74,95,7]

2. 然后根据十位上的数值再将上次排序后的结果分配到不同的盒子中。如下:

queues[5] = 50
queues[9] = 90
queues[8] = 81
queues[9] = 91
queues[1] = 12
queues[7] = 72
queues[0] = 3
queues[7] = 74
queues[9] = 95
queues[0] = 7

最后,将盒子中的数字取出,组成一个新的列表,该列表即为排序好的数字。如下:

即可生成如下:

nums = [3,7,12,50,72,74,81,90,91,95];

如上使用队列列表盒子,可以实现这个算法,我们需要10个队列,每个队列对应一个数字,将所有队列保存在一个数组中,使用取余和除法操作决定个位和十位。算法的剩余部分将数字加入相应的队列,根据个位数值进行重新排序,然后再根据十位上的数值进行排序,结果加入排序好的数字。

下面根据个位或十位上的数值,将数字分配到相应队列的函数。

/*
* 根据个位或十位上的数值,将数字分配到相应队列的函数
* @param digit
* digit=1 表示先按个位来分配
* digit = 10 表示是按十位来分配的
* @param n 表示循环比较多少次 一般数组几个数字就比较多少次
*/
distribute: function(nums,queues,n,digit){
   for(var i = 0; i < n; ++i) {
    if(digit == 1) {
      queues[nums[i] % 10].enqueue(nums[i]);
     }else {
      queues[Math.floor(nums[i] / 10)].enqueue(nums[i]);
     }
   }
}

下面是从队列中收集数字的函数如下:

// 收集数字的函数
collect: function(queues,nums,n) {
  var i = 0;
  for(var digit = 0; digit < n; ++digit) {
    while(!queues[digit].empty()) {
      nums[i++] = queues[digit].dequeue();
    }
  }
}

由于上面省略了很多步骤,可能描述的不是很清楚,我们现在先来看看流程图,结合流程图,最后结合JS的所有代码就可以理解"基数排序的"基本原理了;下面我们可以看看如下的流程图;

JavaScript数据结构与算法之队列原理与用法实例详解

最后是所有的JS代码如下:

function Queue() {
  this.dataStore = [];
}
Queue.prototype = {
  // 向队尾添加一个元素
  enqueue: function(element) {
    this.dataStore.push(element);
  },
  // 删除队首的元素
  dequeue: function(){
    return this.dataStore.shift();
  },
  // 读取队首的元素
  front: function(){
    return this.dataStore[0];
  },
  // 读取队尾的元素
  back: function(){
    return this.dataStore[this.dataStore.length - 1];
  },
  // 显示队列内的所有元素
  toString: function(){
    var retStr = "";
    for(var i = 0; i < this.dataStore.length; ++i) {
      retStr += this.dataStore[i] + "\n";
    }
    return retStr;
  },
  // 判断队列是否为空
  empty: function(){
    if(this.dataStore.length == 0) {
      return true;
    }else {
      return false;
    }
  },
  /*
   * 根据个位或十位上的数值,将数字分配到相应队列的函数
   * @param digit
   * digit=1 表示先按个位来分配
   * digit = 10 表示是按十位来分配的
   * @param n 表示循环比较多少次 一般数组几个数字就比较多少次
   */
  distribute: function(nums,queues,n,digit){
    for(var i = 0; i < n; ++i) {
      if(digit == 1) {
        queues[nums[i] % 10].enqueue(nums[i]);
      }else {
        queues[Math.floor(nums[i] / 10)].enqueue(nums[i]);
      }
    }
  },
  // 收集数字的函数
  collect: function(queues,nums,n) {
    var i = 0;
    for(var digit = 0; digit < n; ++digit) {
      while(!queues[digit].empty()) {
        nums[i++] = queues[digit].dequeue();
      }
    }
  },
  dispArray: function(arr) {
    for(var i = 0; i < arr.length; ++i) {
      console.log(arr[i]);
    }
  }
};

下面的是对 "基数排序的" JS代码进行测试;如下代码:

var q = new Queue();
  q.enqueue("a");
  q.enqueue("b");
  q.enqueue("c");
console.log(q.toString());
q.dequeue();
console.log(q.toString());
console.log("Front of queue:" +q.front());
console.log("Back of queue:" +q.back());
var queues = [];
for(var i = 0; i < 10; ++i) {
   queues[i] = new Queue();
}
var nums = ["50","12","95","7","90","3","74","81","91","72"];
console.log("before radix sort: ");
console.log(nums);
q.distribute(nums,queues,10,1);
q.collect(queues,nums,10);
q.dispArray(nums);
console.log("分割线");
q.distribute(nums,queues,10,10);
q.collect(queues,nums,10);
q.dispArray(nums);

如上测试代码 大家可以运行下 就可以看到排序后的效果!

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
getElementById在任意一款浏览器中都可以用吗的疑问回复
May 13 Javascript
js iframe跨域访问(同主域/非同主域)分别深入介绍
Jan 24 Javascript
jQuery对html元素取值与赋值的方法
Nov 20 Javascript
非jQuery实现照片散落桌子上,单击放大的LightBox效果
Nov 28 Javascript
node.js中的path.delimiter方法使用说明
Dec 09 Javascript
jQuery 实现侧边浮动导航菜单效果
Dec 26 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
Aug 01 Javascript
javascript 动态修改css样式方法汇总(四种方法)
Aug 27 Javascript
JavaScript模拟数组合并concat
Mar 06 Javascript
封装获取dom元素的简单实例
Jul 08 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
Mar 08 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
May 17 jQuery
深入理解Vue官方文档梳理之全局API
Nov 22 #Javascript
初识 Vue.js 中的 *.Vue文件
Nov 22 #Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
Nov 22 #Javascript
基于JavaScript实现表格滚动分页
Nov 22 #Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
Nov 22 #Javascript
Vue官方文档梳理之全局配置
Nov 22 #Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
Nov 22 #Javascript
You might like
消息持续发送的完整例子
2006/10/09 PHP
php 远程图片保存到本地的函数类
2008/12/08 PHP
PHP编码转换函数 自动转换字符集支持数组转换
2012/12/16 PHP
PHP 数组和字符串互相转换实现方法
2013/03/26 PHP
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
Laravel框架路由配置总结、设置技巧大全
2014/09/03 PHP
PHP如何将log信息写入服务器中的log文件
2015/07/29 PHP
四个PHP非常实用的功能
2015/09/29 PHP
自制PHP框架之模型与数据库
2017/05/07 PHP
PHP实现简单日历类编写
2020/08/28 PHP
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
jQuery 获取URL的GET参数值的小例子
2013/04/18 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
2014/05/04 Javascript
JQuery中DOM事件冒泡实例分析
2015/06/13 Javascript
微信小程序之分享页面如何返回首页的示例
2018/03/28 Javascript
vue实现点击当前标签高亮效果【推荐】
2018/06/22 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
vue 实现图片懒加载功能
2020/12/31 Vue.js
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
python实现socket客户端和服务端简单示例
2014/02/24 Python
python制作一个桌面便签软件
2015/08/09 Python
Python ldap实现登录实例代码
2016/09/30 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
python构建深度神经网络(DNN)
2018/03/10 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
Python使用psutil获取进程信息的例子
2019/12/17 Python
HTML5触摸事件(touchstart、touchmove和touchend)的实现
2020/05/08 HTML / CSS
美国高档帽子网上商店:Hats.com
2018/08/09 全球购物
屈臣氏官方旗舰店:亚洲享负盛名的保健及美妆零售商
2019/03/15 全球购物
大学生入党思想汇报
2014/01/14 职场文书
低碳环保标语
2014/06/12 职场文书
党的群众路线教育实践活动个人整改措施材料
2014/11/04 职场文书
学习型家庭事迹材料(2016精选版)
2016/02/29 职场文书