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中使用replaceAll()函数实现字符替换的方法
Dec 25 Javascript
『jQuery』名称冲突使用noConflict方法解决
Apr 22 Javascript
jquery实现图片左右切换的方法
May 07 Javascript
javascript单例模式的简单实现方法
Jul 25 Javascript
Three.js学习之正交投影照相机
Aug 01 Javascript
原生js实现焦点轮播图效果
Jan 12 Javascript
详解vue表单——小白速看
Apr 08 Javascript
详解基于DllPlugin和DllReferencePlugin的webpack构建优化
Jun 28 Javascript
利用es6 new.target来对模拟抽象类的方法
May 10 Javascript
JS前端知识点 运算符优先级,URL编码与解码,String,Math,arguments操作整理总结
Jun 27 Javascript
JS实现灯泡开关特效
Mar 30 Javascript
vue 父组件通过$refs获取子组件的值和方法详解
Nov 07 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
Windows下PHP5和Apache的安装与配置
2006/09/05 PHP
php下封装较好的数字分页方法
2010/11/23 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
PHP中register_globals参数为OFF和ON的区别(register_globals 使用详解)
2012/02/05 PHP
thinkphp autoload 命名空间自定义 namespace
2015/07/17 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
php定期拉取数据对比方法实例
2019/09/22 PHP
jquery与google map api结合使用 控件,监听器
2010/03/04 Javascript
js清空表单数据的两种方式(遍历+reset)
2014/07/18 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
Vue请求java服务端并返回数据代码实例
2019/11/28 Javascript
从零使用TypeScript开发项目打包发布到npm
2020/02/14 Javascript
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
Python代理抓取并验证使用多线程实现
2013/05/03 Python
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
Python实现嵌套列表及字典并按某一元素去重复功能示例
2017/11/30 Python
pandas 透视表中文字段排序方法
2018/11/16 Python
Django框架基础模板标签与filter使用方法详解
2019/07/23 Python
python爬虫selenium和phantomJs使用方法解析
2019/08/08 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
HTML5 Canvas玩转酷炫大波浪进度图效果实例(附demo)
2016/12/14 HTML / CSS
Html5获取高德地图定位天气的方法
2019/12/26 HTML / CSS
教师演讲稿范文
2014/01/08 职场文书
企业授权委托书范本
2014/04/02 职场文书
计生专干事迹
2014/05/28 职场文书
高中班级口号
2014/06/09 职场文书
龙门石窟导游词
2015/02/02 职场文书
房地产销售主管岗位职责
2015/02/13 职场文书
留学推荐信英文范文
2015/03/26 职场文书
银行反洗钱宣传活动总结
2015/05/08 职场文书
纪律委员竞选稿
2015/11/19 职场文书
goland 恢复已更改文件的操作
2021/04/28 Golang
JavaScript组合继承详解
2021/11/07 Javascript
Python实现简单得递归下降Parser
2022/05/02 Python