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 相关文章推荐
关于Blog顶部的滚动导航条代码
Sep 25 Javascript
静态页面的值传递(三部曲)
Sep 25 Javascript
javascript+xml技术实现分页浏览
Jul 27 Javascript
js escape,unescape解决中文乱码问题的方法
May 26 Javascript
jquery移动节点实例
Jan 14 Javascript
JavaScript脚本判断蜘蛛来源的方法
Sep 22 Javascript
JavaScript中的高级函数
Jan 04 Javascript
react项目实践之webpack-dev-serve
Sep 14 Javascript
vue使用微信JS-SDK实现分享功能
Aug 23 Javascript
webpack是如何实现模块化加载的方法
Nov 06 Javascript
JS sort方法基于数组对象属性值排序
Jul 10 Javascript
微信小程序自定义yPicker组件实现省市区三级联动功能
Oct 29 Javascript
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
不用数据库的多用户文件自由上传投票系统(3)
2006/10/09 PHP
Discuz!5的PHP代码高亮显示插件(黑暗中的舞者更新)
2007/01/29 PHP
第4章 数据处理-php字符串的处理-郑阿奇(续)
2011/07/04 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】
2018/04/27 PHP
Laravel使用Queue队列的技巧汇总
2019/09/02 PHP
Laravel框架实现的上传图片到七牛功能详解
2019/09/06 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
javascript客户端解决方案 缓存提供程序
2010/07/14 Javascript
Dom操作之兼容技巧分享
2011/09/20 Javascript
JS动态显示表格上下frame的方法
2015/03/31 Javascript
JS禁用页面上所有控件的实现方法(附demo源码下载)
2015/12/17 Javascript
复杂的javascript窗口分帧解析
2016/02/19 Javascript
jQuery无刷新上传之uploadify3.1简单使用
2016/06/18 Javascript
Vue数据驱动模拟实现3
2017/01/11 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
JavaScript之Date_动力节点Java学院整理
2017/06/28 Javascript
前端主流框架vue学习笔记第一篇
2017/07/26 Javascript
使用Angular CLI生成路由的方法
2018/03/24 Javascript
Async/Await替代Promise的6个理由
2019/06/15 Javascript
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
巧用Python装饰器 免去调用父类构造函数的麻烦
2012/05/18 Python
Python双向循环链表实现方法分析
2018/07/30 Python
Python 串口读写的实现方法
2019/06/12 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
python+opencv实现移动侦测(帧差法)
2020/03/20 Python
浅谈Python中的字符串
2020/06/10 Python
安装pyinstaller遇到的各种问题(小结)
2020/11/20 Python
python excel多行合并的方法
2020/12/09 Python
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
企划专员岗位职责
2013/12/09 职场文书
中考冲刺决心书
2014/03/11 职场文书
关于幸福的感言
2015/08/03 职场文书
2016银行求职自荐信
2016/01/28 职场文书
基于PyTorch实现一个简单的CNN图像分类器
2021/05/29 Python