张三丰教无忌太极剑法: 还记得吗? 全都记得. 如今呢? 已经忘却了一小半. 啊,已经忘了一大半. 不坏不坏,忘得真快,那么如今呢? 已经全都忘了,忘得干干净净. 好了,你上吧.
长时间写前端代码,将本身之前的积累都忘得一干二净,因此开了一个关于JS的数据结构系列,在业务型程序员的基础上,也要实时的优化本身的代码,让本身的代码有思想是每一个程序员最自豪的事情。html
本文目录前端
相信任何有些编程基础的人都对队列不算陌生,队列是一种先进先出的接口,也就是FIFO(First Input First Output),它也是一种表结构。在队列的队尾插入数据,在队首删除数据,能够想象成咱们天天早晨买豆浆时队伍。程序员
队列只要有两个主要的功能:出队(push)和入队(pop)。入队操做在队尾插入新的元素,出队操做返回并删除队首的元素。有时候咱们只须要获取队首和队尾但并不必定非要执行队列的出队和入队行为,因此咱们又须要一个获取队首(getFirst)和队尾(getLast)的行为。有时咱们也有所有清空本队列的动做,因此还要有clear方法。除了以上提到的咱们还须要知道队列中有多少个元素,能够用length去获取。算法
使用数组的push方法和shift方法能够基本完成队列的出队和入队操做,可是咱们为了避免让其余无关的数组属性去破坏队列结构还须要对其封装一下,因此就有了咱们如今的代码:编程
function Queue(){ var items = []; //入队 this.push = function(obj){ items.push(obj); }; //出队 this.pop = function(){ return items.shift(); }; //获取队首 this.getFirst = function(){ return items[0]; }; //获取队尾 this.getLast = function(){ return items[items.length-1]; }; //清空本队列 this.clear = function(){ items = []; } //获取队列指定位置 this.get = function(k){ return items[k]; }; //获取队列长度 this.length = function(){ return items.length; }; //队列是否为空 this.empty = function(){ return items.length === 0; }; } var lazyQueue = new Queue(); lazyQueue.push({ a: 1, b: 2 }); lazyQueue.push({ c: 3, d: 4 }); console.log(lazyQueue.pop()); console.log(lazyQueue.length()); console.log(lazyQueue.clear()); console.log(lazyQueue.pop()); console.log(lazyQueue.length());
输出结果为:数组
{a: 1, b: 2} 1 undefined undefined 0
在咱们的开发遇到不少队列的使用,且队列的应用也比较简单,只要在执行完上次任务后再执行本任务,直到队列为空为止。数据结构
以前分享了PHP以及JavaScript的八大排序方式,可是对于基数排序的JavaScript实现方法没有搞清楚,如今能够补上了。dom
首先将“基数排序”的概念理解一下: 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的做用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采起的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。(取自百度百科)优化
咱们一样以百度百科中的列子:假若有数字: 73, 22, 93, 43, 55, 14, 28, 65, 39, 81this
通过基数排序第一次扫描以后按照个位数的大小排序,数字被分配大以下的盒子中:
第0个盒子: 第1个盒子:81 第2个盒子:22 第3个盒子:73, 93, 43 第4个盒子:14 第5个盒子:55, 65 第6个盒子: 第7个盒子: 第8个盒子:28 第9个盒子:39
根据盒子的顺序,对数字经行第一次排序的结果以下:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
而后根据十位上的数值再将上次排序结果分配到不一样的盒子里
第0个盒子: 第1个盒子:14 第2个盒子:22, 28 第3个盒子:39 第4个盒子:43 第5个盒子:55 第6个盒子:65 第7个盒子:73 第8个盒子:81 第9个盒子:93
最后将盒子里的数字取出,组成一个新的列表,该列表即为排好顺序的数字:
14, 22, 28, 39 ,43, 55, 65, 73, 81, 93
使用队列表明盒子,能够实现这个算法,咱们须要9个队列,每一个对应一个数字。将全部队列保存在一个数组中,使用取余和出发操做决定各位和十位。算法的剩余部分将数字加入对应的队列,根据个位数值从新排序,而后再根据十位数值经行排序,结果即为排好顺序的数字。
function Queue(){ var items = []; //入队 this.push = function(obj){ items.push(obj); }; //出队 this.pop = function(){ return items.shift(); }; //获取队首 this.getFirst = function(){ return items[0]; }; //获取队尾 this.getLast = function(){ return items[items.length-1]; }; //清空本队列 this.clear = function(){ items = []; } //获取队列指定位置 this.get = function(k){ return items[k]; }; //获取队列长度 this.length = function(){ return items.length; }; //队列是否为空 this.empty = function(){ return items.length == 0; }; } /********基数排序**********/ //初始化队列 var queues = []; for (var i = 0; i <10; i++){ queues[i] = new Queue(); } //随机产生10个二位的整数 var nums = []; for (var i = 0; i < 10; i++) { nums[i] = Math.floor(Math.random()*100); } console.log('初始化数组:', nums); //按照个位数字入相应的队列 for (var i=0; i<10; i++) { queues[nums[i]%10].push(nums[i]); } //收集队列中的数字放在数组nums中 var j=0; var nums2 = []; for (var i=0; i<10; i++) { while (!queues[i].empty()){ nums2[j++] = queues[i].pop(); } } console.log('个位数字入队排序后的数组:', nums2); //因为上面已经所有出队了,因此可使用已经初始化的queue队列数组 //按照十位数字入相应的队列 for (var i = 0; i < 10; i++) { !isNaN(Math.floor(nums2[i] / 10)) && queues[Math.floor(nums2[i] / 10)].push(nums2[i]); } //收集队列中的数字放在数组nums中 j=0; var nums3 = [] for (var i=0; i<10; i++) { while (!queues[i].empty()){ nums3[j++] = queues[i].pop(); } } console.log('十位数字入队排序后的数组:', nums3);
结果以下:
初始化数组: [15, 48, 46, 77, 23, 72, 93, 25, 0, 75] 个位数字入队排序后的数组: [0, 72, 23, 93, 15, 25, 75, 46, 77, 48] 十位数字入队排序后的数组: [0, 15, 23, 25, 46, 48, 72, 75, 77, 93]