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 CSS画图之基础篇
Jul 29 Javascript
在图片上显示左右箭头类似翻页的代码
Mar 04 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
Aug 18 Javascript
jQuery焦点图切换简易插件制作过程全纪录
Aug 27 Javascript
js获取浏览器基本信息大全
Nov 27 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
May 03 Javascript
jQuery实现美观的多级动画效果菜单代码
Sep 06 Javascript
JS操作COOKIE实现备忘记录的方法
Apr 01 Javascript
详解Bootstrap各式各样的按钮(推荐)
Dec 13 Javascript
angularjs项目的页面跳转如何实现(5种方法)
May 25 Javascript
微信小程序--获取用户地理位置名称(无须用户授权)的方法
Apr 29 Javascript
js中console在一行内打印字符串和对象的方法
Sep 10 Javascript
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
让你同时上传 1000 个文件 (二)
2006/10/09 PHP
完美实现GIF动画缩略图的php代码
2011/01/02 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
thinkPHP5实现的查询数据库并返回json数据实例
2017/10/23 PHP
asp.net 30分钟掌握无刷新 Repeater
2011/09/16 Javascript
解决jquery的datepicker的本地化以及Today问题
2012/05/23 Javascript
JQuery each()嵌套使用小结
2014/04/18 Javascript
jquery ztree实现下拉树形框使用到了json数据
2014/05/14 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
node.js+Ajax实现获取HTTP服务器返回数据
2014/11/26 Javascript
CSS3,HTML5和jQuery搜索框集锦
2014/12/02 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
2015/12/03 Javascript
javascript实现列表切换效果
2016/05/02 Javascript
canvas实现动态小球重叠效果
2017/02/06 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
jQuery实现新闻播报滚动及淡入淡出效果示例
2018/03/23 jQuery
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
vue实现滑动到底部加载更多效果
2020/10/27 Javascript
js实现的在本地预览图片功能示例
2019/11/09 Javascript
Python生成随机数的方法
2014/01/14 Python
详解Python设计模式编程中观察者模式与策略模式的运用
2016/03/02 Python
python处理xml文件的方法小结
2017/05/02 Python
Python中按键来获取指定的值
2019/03/02 Python
Python3.5内置模块之time与datetime模块用法实例分析
2019/04/27 Python
Django如何自定义model创建数据库索引的顺序
2019/06/20 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
Spring实战之使用util:命名空间简化配置操作示例
2019/12/09 Python
Shopee印度尼西亚:东南亚与台湾市场最大电商平台
2018/06/17 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
建筑班组长岗位职责
2014/01/02 职场文书
六年级数学教学反思
2014/02/03 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
MySQL Innodb关键特性之插入缓冲(insert buffer)
2021/04/08 MySQL
php去除deprecated的实例方法
2021/11/17 PHP