JavaScript数据结构与算法之栈详解


Posted in Javascript onMarch 12, 2015

在上一篇博客介绍了下列表,列表是最简单的一种结构,但是如果要处理一些比较复杂的结构,列表显得太简陋了,所以我们需要某种和列表类似但是更复杂的数据结构---栈。栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样操作很快,而且容易实现。

一:对栈的操作。

栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端陈为栈顶。比如餐馆里面洗盘子,只能先洗最上面的盘子,盘子洗完后,也只能螺到这一摞盘子的最上面。栈被称为 "后入先出"(LIFO)的数据结构。

由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问,为了得到栈低的元素,必须先拿掉上面的元素。我们可以对栈的两种主要操作是将一个元素 压入栈 和 将一个元素 弹出栈。入栈我们可以使用方法push()方法,出栈我们使用pop()方法。pop()方法虽然可以访问栈顶的元素,但是调用该方法后,栈顶元素也就从栈中被永久性的删除了。另一个我们很常用的方法是peek(),该方法只返回栈顶元素,而不删除它。

入栈和出栈的实列图如下:

JavaScript数据结构与算法之栈详解

push(),pop()和peek()是栈的三个主要方法,但是栈还有其他方法和属性。如下:

clear():清除栈内的所有元素。

length(): 记录栈内元素的个数。

二:对栈的实现如下:

我们可以先实现栈类的方法开始;如下:
 

  function Stack() {

      this.dataStore = [];

      this.top = 0;

  }

 

 如上:dataStore 是保存栈内的所有元素。变量top记录栈顶的位置,初始化为0. 表示栈顶对应数组的起始位置为0,如果有元素被压入栈。该变量值将随之变化。

我们还有如下几个方法:push(), pop(), peek(),clear(),length();

1.  push()方法;当向栈内压入一个新元素时,需要将其保存在数组中变量top所对应的位置,然后top值加1,让其指向数组中下一个位置。如下代码:

function  push(element) {

     this.dataStore[this.top++] = element;

}

2. pop()方法与push()方法相反---它返回栈顶元素,同时将top值减1.如下代码:
   function pop(){

       return this.dataStore[--this.top];

   }

3. peek()方法返回数组的第top-1个位置的元素,即栈顶元素;
    function peek(){

        return this.dataStore[this.top - 1];

    }

4. length()方法 有时候我们要知道栈内有多少个元素,我们可以通过返回变量top值的方式返回栈内的元素个数,如下代码:
     function length(){

         return this.top;

     }

5. clear(); 有时候我们要清空栈,我们将变量top值设为0;如下代码:
   function clear() {
        this.top = 0;
    }

如下所有代码:
function Stack() {

    this.dataStore = [];

    this.top = 0;

}
Stack.prototype = {

    

    // 向栈中压入一个新元素

    push: function(element) {

        this.dataStore[this.top++] = element;

    },

    // 访问栈顶元素,栈顶元素永久的被删除了

    pop: function(){

        return this.dataStore[--this.top];

    },

    // 返回数组中的 top-1 个位置的元素,即栈顶元素

    peek: function(){

        return this.dataStore[this.top - 1];

    },

    // 栈内存储了多少个元素

    length: function(){

        return this.top;

    },

    // 清空栈

    clear: function(){

        this.top = 0;

    }

};
demo实例如下:
var stack = new Stack();

stack.push("a");

stack.push("b");

stack.push("c");

console.log(stack.length()); // 3

console.log(stack.peek());   // c
var popped = stack.pop();

console.log(popped);  // c
console.log(stack.peek()); // b
stack.push("d");
console.log(stack.peek());  // d
stack.clear();
console.log(stack.length());  // 0
console.log(stack.peek());  // undefined

下面我们可以实现一个阶乘函数的递归定义;比如5!的阶乘 5!= 5 * 4 * 3 * 2 * 1;

如下代码:

function fact(n) {

    var s = new Stack();

    while(n > 1) {

        s.push(n--);

    }

    var product = 1;

    while(s.length() > 0) {

        product *= s.pop();

    }

    return product;

}

console.log(fact(5));

上面的代码含义是:先数字5传入函数,使用while循环,每次自减1的之前,把自己使用栈的函数push()压入栈内,直到变量n  小于 1为止。然后定义一个变量product;通过栈的length()的方法判断是否大于0 且每次执行 product* = s.pop();  pop()方法返回栈顶元素,且从栈中删掉该元素。所以每次执行一次,就删掉一个元素,直到s.length() <= 0 为止。所以 product = 5*4*3*2*1 .等操作。

Javascript 相关文章推荐
JavaScript 对象成员的可见性说明
Oct 16 Javascript
jQuery入门问答 整理的几个常见的初学者问题
Feb 22 Javascript
Javascript公共脚本库系列(一): 弹出层脚本
Feb 24 Javascript
轮播图组件js代码
Aug 08 Javascript
Node.js使用NodeMailer发送邮件实例代码
Mar 06 Javascript
微信小程序开发图片拖拽实例详解
May 05 Javascript
Angular2仿照微信UI实现9张图片上传和预览的示例代码
Oct 19 Javascript
js限制输入框只能输入数字(onkeyup触发)
Sep 28 Javascript
基于vue-upload-component封装一个图片上传组件的示例
Oct 16 Javascript
Vue对象赋值视图不更新问题及解决方法
Jun 03 Javascript
Websocket 向指定用户发消息的方法
Jan 09 Javascript
Vue实现简单计算器
Jan 20 Vue.js
jQuery实现简单的日期输入格式化控件
Mar 12 #Javascript
Javascript数据结构与算法之列表详解
Mar 12 #Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
Mar 12 #Javascript
基于jquery实现的自动补全功能
Mar 12 #Javascript
jquery实现页面百叶窗走马灯式翻滚显示效果的方法
Mar 12 #Javascript
window.open()实现post传递参数
Mar 12 #Javascript
js运动动画的八个知识点
Mar 12 #Javascript
You might like
Discuz! Passport 通行证整合
2008/03/27 PHP
php取整函数ceil,floo,round的用法及介绍
2013/08/31 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
php简单统计中文个数的方法
2016/09/30 PHP
php实现微信支付之企业付款
2018/05/30 PHP
javascript eval函数深入认识
2009/02/21 Javascript
文本框中,回车键触发事件的js代码[多浏览器兼容]
2010/06/07 Javascript
jquery 操作表格实现代码(多种操作打包)
2011/03/20 Javascript
jQuery中[attribute^=value]选择器用法实例
2014/12/31 Javascript
JavaScript通过HTML的class来获取HTML元素的方法总结
2016/05/24 Javascript
Vue.js每天必学之组件与组件间的通信
2016/09/08 Javascript
JS+CSS3制作炫酷的弹窗效果
2016/11/08 Javascript
Node.js中 __dirname 的使用介绍
2017/06/19 Javascript
vue-router动态设置页面title的实例讲解
2018/08/30 Javascript
Vue一次性简洁明了引入所有公共组件的方法
2018/11/28 Javascript
简单实现vue中的依赖收集与响应的方法
2019/02/18 Javascript
node实现简单的增删改查接口实例代码
2019/08/22 Javascript
[01:32]TI珍贵瞬间系列(一)
2020/08/26 DOTA
wxPython中文教程入门实例
2014/06/09 Python
Python实现对PPT文件进行截图操作的方法
2015/04/28 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
Python实现打印螺旋矩阵功能的方法
2017/11/21 Python
python中的set实现不重复的排序原理
2018/01/24 Python
selenium+python自动化测试之环境搭建
2019/01/23 Python
解决Python安装时报缺少DLL问题【两种解决方法】
2019/07/15 Python
pycharm不能运行.py文件的解决方法
2020/02/12 Python
Python数据正态性检验实现过程
2020/04/18 Python
python怎么判断模块安装完成
2020/06/19 Python
浅谈Python里面None True False之间的区别
2020/07/09 Python
Python如何执行精确的浮点数运算
2020/07/31 Python
python 线程的五个状态
2020/09/22 Python
日本非常有名的内衣丝袜品牌:GUNZE
2017/01/06 全球购物
军训的自我鉴定
2013/12/10 职场文书
人间正道是沧桑观后感
2015/06/15 职场文书
《叶问2》观后感
2015/06/15 职场文书
2015年社区国庆节活动总结
2015/07/30 职场文书