JavaScript数据结构与算法之栈与队列


Posted in Javascript onJanuary 29, 2016

学习起因

曾经有一次在逛V2EX时,碰到这么一个帖子。
数学完全还给老师了,想学回一些基础数学,大概是高中程度的,有什么书籍推荐?
发帖的楼主大学没有高数课程,出去工作时一直在从事前端的工作。感觉到数学知识的匮乏,所以想补一补数学。
看了看帖子,感觉和我很像,因为我的专业是不开高数的,我学的也是前端。也同样感觉到了数学知识匮乏所带来的困顿。同时因为自己的数学思维实在是不怎么好,所以决定努力补习数学与计算机基础知识。
当时也有人说:”前端需要什么数据结构与算法”,但是对于这个事情我有自己的看法。
我并不认为前端不需要算法之类的知识,在我看来前端具备坚实的计算机基础,对自身发展是极其有利的。我想做程序员。而不是一辈子的初级前端和码农。
也算是给自己的勉励吧。毕竟基础决定上限,再加上自己对计算机真的很感兴趣,所以学起来就算很累,但也是很幸福的。于是去网上选购了《学习JavaScript数据结构与算法》这本书,配合着去图书馆借阅的《大话数据结构》,开始了数据结构与算法的初步学习。

JavaScipt之数组操作

接下来就是数据结构的第一部分,栈。
栈是一种遵从后进先出原则(LIFO,全称为Last In First Out)的有序集合。栈顶永远是最新的元素。
举个例子就是:栈就像放在箱子里的一叠书 你要拿下面的书先要把上面的书拿开。(当然,你不能先拿下面的书。)

JavaScipt中栈的实现
首先,创建一个构造函数。

/**
 * 栈的构造函数
 */
function Stack() {

 // 用数组来模拟栈
 var item = [];
}

栈需要有如下的方法:
push(element(s)): 添加几个元素到栈顶
pop(): 移除并返回栈顶元素
peek(): 返回栈顶元素
isAmpty: 检查栈是否为空,为空则返回true
clear: 移除栈中所有元素
size: 返回栈中元素个数。
print: 以字符串显示栈中所有内容
push方法的实现
说明: 需要往栈中添加新元素,元素位置在队列的末尾。也就是说,我们可以用数组的push方法来模拟实现。

实现:

/**
 * 将元素送入栈,放置于数组的最后一位
 * @param {Any} element 接受的元素,不限制类型
 */
this.push = function(element) {
 items.push(element);
};

pop方法的实现

说明: 需要把栈顶元素弹出,同时返回被弹出的值。可以用数组的pop方法来模拟实现。
实现:

/**
 * 弹出栈顶元素
 * @return {Any} 返回被弹出的值
 */
this.pop = function() {
 return items.pop();
};

peek方法的实现
说明: 查看栈顶元素,可以用数组长度来实现。
实现:

/**
 * 查看栈顶元素
 * @return {Any} 返回栈顶元素
 */
this.peek = function() {
 return items[items.length - 1];
}

其余方法的实现
说明: 前三个是栈方法的核心,其余方法则在此一次性列出。因为下文要讲的队列,会与这部分有很大重合。
实现:

/**
 * 确定栈是否为空
 * @return {Boolean} 若栈为空则返回true,不为空则返回false
 */
this.isAmpty = function() {
 return items.length === 0
};

/**
 * 清空栈中所有内容
 */
this.clear = function() {
 items = [];
};

/**
 * 返回栈的长度
 * @return {Number} 栈的长度
 */
this.size = function() {
 return items.length;
};

/**
 * 以字符串显示栈中所有内容
 */
this.print = function() {
 console.log(items.toString());
};

实际应用

栈的实际应用比较多,书中有个十进制转二进制的函数。(不懂二进制怎么算的话可以百度)下面是函数的源代码。
原理就是输入要转换的数字,不断的除以二并取整。并且最后运用while循环,将栈中所有数字拼接成字符串输出。

/**
 * 将10进制数字转为2进制数字
 * @param {Number} decNumber 要转换的10进制数字
 * @return {Number}      转换后的2进制数字
 */
function divideBy2(decNumber) {

 var remStack = new Stack(),
  rem,
  binaryString = '';

 while (decNumber > 0) {
  rem = Math.floor(decNumber % 2);
  remStack.push(rem);
  decNumber = Math.floor(decNumber / 2);
 }

 while (!remStack.isAmpty()) {
  binaryString += remStack.pop().toString();
 }

 return binaryString;
};

到此而言,栈的学习就告一段落了。因为源代码中注释较多,所以这儿就不贴出源代码的内容了。

队列

队列与栈是很相像的数据结构,不同之处在于队列是是先进先出(FIFO:First In First Out)的。
举个例子: 火车站排队买票,先到的先买。(插队的不算),是不是很好理解了~

JavaScipt中队列的实现

队列的实现和栈很像。首先依然是构造函数:

/**
 * 队列构造函数
 */
function Queue() {
 var items = [];
}

队列需要有如下的方法:
enqueue(element(s)): 向队列尾部添加几个项
dequeue(): 移除队列的第一项(也就是排在最前面的项)
front(): 返回队列的第一个元素,也就是最新添加的那个
其余方法与队列相同

enqueue方法的实现

说明: 向队列尾部添加几个项。
实现:

/**
 * 将元素推入队列尾部
 * @param {Any} ele 要推入队列的元素
 */
this.enqueue = function(ele) {
 items.push(ele);
};

dequeue方法的实现

说明: 移除队列的第一项。
实现:

/**
 * 将队列中第一个元素弹出
 * @return {Any} 返回被弹出的元素
 */
this.dequeue = function() {
 return items.shift()
};

front方法的实现

说明: 返回队列的第一个元素,也就是最新添加的那个。
实现:

/**
 * 查看队列的第一个元素
 * @return {Any} 返回队列中第一个元素
 */
this.front = function() {
 return items[0];
};

以上的三个方法,就是队列这种数据结构的核心方法了。其实很好理解的。

实际应用
书上的是个击鼓传花的小游戏。原理就是循环到相应位置时,队列弹出那个元素。最后留下的就是赢家。
源代码如下:

/**
 * 击鼓传花的小游戏
 * @param {Array} nameList 参与人员列表
 * @param {Number} num   在循环中要被弹出的位置
 * @return {String}     返回赢家(也就是最后活下来的那个)
 */
function hotPotato(nameList, num) {
 var queue = new Queue();

 for (var i = 0; i < nameList.length; i++) {
  queue.enqueue(nameList[i]);
 }

 var eliminated = '';

 while (queue.size() > 1) {
  for (var i = 0; i < num; i++) {
   queue.enqueue(queue.dequeue());
  }

  eliminated = queue.dequeue();
  console.log(eliminated + " Get out!")
 }

 return queue.dequeue()
}

队列的学习到此就告一段落了。下一期将讲述另外一种数据结构: 链表。

感想

很多时候看书,直接看算法导论或者一些数据结构的书,都是很迷糊的。后来才发现,看书从自己能看懂的开始,由浅入深才是适合自己的学习方式。

Javascript 相关文章推荐
javascript之函数直接量(function(){})()
Jun 29 Javascript
JavaScript入门教程(8) Location地址对象
Jan 31 Javascript
JavaScript生成GUID的多种算法小结
Aug 18 Javascript
JavaScript SetInterval与setTimeout使用方法详解
Nov 15 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
Dec 17 Javascript
修复bash漏洞的shell脚本分享
Dec 31 Javascript
JavaScript模拟可展开、拖动与关闭的聊天窗口实例
May 12 Javascript
用JavaScript动态建立或增加CSS样式表的实现方法
May 20 Javascript
你不知道的 javascript【推荐】
Jan 08 Javascript
微信小程序中hidden不生效原因的解决办法
Apr 26 Javascript
js实现图片实时时钟
Jan 15 Javascript
vue中利用three.js实现全景图的完整示例
Dec 07 Vue.js
javascript实现表单验证
Jan 29 #Javascript
jQuery实现横向带缓冲的水平运动效果(附demo源码下载)
Jan 29 #Javascript
JavaScript判断DIV内容是否为空的方法
Jan 29 #Javascript
基于javascript实现listbox左右移动
Jan 29 #Javascript
关于获取DIV内部内容报错的原因分析及解决办法
Jan 29 #Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
Jan 29 #Javascript
js实现滚动条滚动到某个位置便自动定位某个tr
Jan 20 #Javascript
You might like
php中用于检测一个地理IP地址是否可用的代码
2012/02/19 PHP
腾讯微博提示missing parameter errorcode 102 错误的解决方法
2014/12/22 PHP
php实现curl模拟ftp上传的方法
2015/07/29 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
prototype1.4中文手册
2006/09/22 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
js 实现的可折叠留言板(附源码下载)
2014/07/01 Javascript
JavaScript的Vue.js库入门学习教程
2016/05/23 Javascript
Ionic快速安装教程
2016/06/03 Javascript
jQuery on()方法绑定动态元素的点击事件无响应的解决办法
2016/07/07 Javascript
AJAX和jQuery动态加载数据的实现方法
2016/12/05 Javascript
BootstrapValidator超详细教程(推荐)
2016/12/07 Javascript
BootStrap便签页的简单应用
2017/01/06 Javascript
jQuery插件ajaxFileUpload使用详解
2017/01/10 Javascript
轻松学习Javascript闭包
2017/03/01 Javascript
Angular2安装angular-cli
2017/05/21 Javascript
详解vue中使用express+fetch获取本地json文件
2017/10/10 Javascript
webpack vue项目开发环境局域网访问方法
2018/03/20 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
JS面向对象编程基础篇(一) 对象和构造函数实例详解
2020/03/03 Javascript
python使用pyhook监控键盘并实现切换歌曲的功能
2014/07/18 Python
Python遍历zip文件输出名称时出现乱码问题的解决方法
2015/04/08 Python
pandas数据预处理之dataframe的groupby操作方法
2018/04/13 Python
python实现三维拟合的方法
2018/12/29 Python
Python变量、数据类型、数据类型转换相关函数用法实例详解
2020/01/09 Python
django 模型中的计算字段实例
2020/05/19 Python
JD Sports瑞典:英国领先的运动时尚商店
2018/01/28 全球购物
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
UNIONBAY官网:美国青少年服装品牌
2019/03/26 全球购物
党员实事承诺书
2014/03/26 职场文书
访谈节目策划方案
2014/05/15 职场文书
企业文化标语大全
2014/06/10 职场文书
普通党员四风问题对照检查材料
2014/09/27 职场文书
查摆问题整改措施范文
2014/10/11 职场文书
2016新年慰问信范文
2015/03/25 职场文书