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 相关文章推荐
实现JavaScript中继承的三种方式
Oct 16 Javascript
基于jquery的loading效果实现代码
Nov 05 Javascript
jquery ajax请求实例深入解析
Nov 26 Javascript
javascript引用赋值(地址传值)用法实例
Jan 13 Javascript
D3.js中data(), enter() 和 exit()的问题详解
Aug 17 Javascript
JS集成fckeditor及判断内容是否为空的方法
May 27 Javascript
详解Angular中$cacheFactory缓存的使用
Aug 19 Javascript
bootstrap模态框远程示例代码分享
May 22 Javascript
bootstrap轮播模板使用方法详解
Nov 17 Javascript
浅谈Vue初学之props的驼峰命名
Jul 19 Javascript
ES6函数和数组用法实例分析
May 23 Javascript
详解CocosCreator项目结构机制
Apr 14 Javascript
深入理解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
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
php AJAX实例根据邮编自动完成地址信息
2008/11/23 PHP
php代码审计比较有意思的例子
2014/05/07 PHP
Codeigniter注册登录代码示例
2014/06/12 PHP
如何优雅的使用 laravel 的 validator验证方法
2018/11/11 PHP
jquery简单的拖动效果实现原理及示例
2013/07/26 Javascript
JQuery实现倒计时按钮具体方法
2013/11/14 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
用vue写一个仿简书的轮播图的示例代码
2018/03/13 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
2018/07/10 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
JavaScript(js)处理的HTML事件、键盘事件、鼠标事件简单示例
2019/11/19 Javascript
[02:30]DOTA2放量测试专访海涛:呼吁保护新手玩家
2013/08/26 DOTA
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
Python http接口自动化测试框架实现方法示例
2018/12/06 Python
如何运行.ipynb文件的图文讲解
2019/06/27 Python
python二进制读写及特殊码同步实现详解
2019/10/11 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
Pytorch自己加载单通道图片用作数据集训练的实例
2020/01/18 Python
浅谈对python中if、elif、else的误解
2020/08/20 Python
cookies应对python反爬虫知识点详解
2020/11/25 Python
Python基于mediainfo批量重命名图片文件
2020/12/29 Python
python+selenium+chrome实现淘宝购物车秒杀自动结算
2021/01/07 Python
如何查看python关键字
2021/01/17 Python
python openpyxl模块的使用详解
2021/02/25 Python
CSS3制作ajax loader icon实现思路及代码
2013/08/25 HTML / CSS
澳大利亚冲浪和时尚服装网上购物:SurfStitch
2017/07/29 全球购物
师范生个人推荐信
2013/11/29 职场文书
公司行政经理岗位职责
2013/12/24 职场文书
庆元旦活动总结
2014/07/09 职场文书
基层党支部整改方案
2014/10/25 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书