JavaScript数据结构——栈的实现

  栈(stack)是一种运算受限的线性表。栈内的元素只允许通过列表的一端访问,这一端被称为栈顶,相对地,把另一端称为栈底。装羽毛球的盒子是现实中常见的栈例子。栈被称为一种后入先出(LIFO,last-in-first-out)的数据结构。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

  下图演示了入栈和出栈的过程:

  

  我们知道pop()方法虽然可以访问栈顶元素,但是调用该方法后,栈顶元素被删除,而peek()方法返回栈顶元素,并不改变栈。push(),pop(),peek()是实现栈的三个主要方法,下表定义了栈的主要方法:

主要方法及属性
dataStorage Array 存储数据的底层数据结构
top int 记录栈顶元素位置
push fucntion 入栈方法
pop fucntion 出栈方法
peek fucntion 返回栈顶元素
length     fucntion   返回栈内元素个数
clear function   清空栈元素

  

 

 

 

 

 

 

栈的实现

  构造方法:  

1 function Stack() {
2     this.dataStorage = [];
3     this.top = 0;
4     this.push = push;
5     this.pop = pop;
6     this.peek = peek;
7     this.length = length;
8     this.clear = clear;
9 }

  我们用数组来存储栈内元素,构造方法将其初始化为一个空数组,变量top记录栈顶元素位置,被构造方法初始化为0,表示栈顶元素的初始位置为0,当有元素入栈,top也随之改变。

  push()方法的实现:  

1 function push(element) {
2     this.dataStorage[this.top++] = element;//将元素保存在数组top位置,并指向下一空位置
3 }

  当向栈中压入一个新元素时,需要将其保存在数组中变量 top 所对应的位置,然后将 top 值加 1,让其指向数组中下一个空位置。这里要特别注意 ++ 操作符的位置,它放在 this.top 的后面,这样新入栈的元素就被放在top 的当前值对应的位置,然后再将变量 top 的值加 1,指向下一个空位置。

  pop方法的实现:  

1 function pop() {
2     return this.dataStorage[--this.top];//返回数组top位置的元素,并让top指向top-1位置元素
3 }

  pop() 方法恰好与 push() 方法相反——它返回栈顶元素,同时将变量 top 的值减 1。

  peek() 方法的实现:  

1 function peek() {
2     return this.dataStorage[this.top-1];//返回数组top-1位置的元素
3 }

  这里需要考虑到空栈调用peek方法时候,返回的是-1位置元素,为undefined。

  length()方法的实现:  

1 function length() {
2     return this.top;
3 }

  如果需要知道栈内到底存了多少个元素,可通过调用length()方法,栈元素的个数即top的值。

  清空栈clear()饭方法的实现:

1 function clear() {
2     this.top = 0;
3 }

  将top设置为0,即栈顶元素位置为0,此时为空栈。

  下面我们来测试下: 

 1         var s = new Stack();
 2         s.push("a");//向栈顶压入元素
 3         s.push("b");
 4         s.push("c");
 5         console.log(s.length());//输出栈内元素个数 
 6         console.log(s.pop());//返回栈顶元素并删除
 7         console.log(s.length());
 8         console.log(s.peek());//返回栈顶元素不删除
 9         s.clear();
10         console.log(s.length());
11         console.log(s.peek());

  输出结果:

  

  最后一行返回undefined,是因为栈内元素被清空后,栈顶无值。

  Stack实际应用  

  我们来模拟一个简单的递归过程,计算数的阶乘。

  先使用递归实现:  

1 function Factorial(num) {
2             if (num == 0) {
3                 return 1;//0的阶乘为1
4             } else {
5                 return num*Factorial(num - 1);
6             }
7 
8         }

  用栈来计算,首先需要将数字1~num全部压入栈,然后将数字连乘。 

 1         function StackFactorial(num) {
 2             var stack = new Stack();
 3             while (num > 1) {
 4                 stack.push(num--);//将1~num压入栈
 5             }
 6             var result = 1;
 7             while (stack.length() > 0) {
 8                 result *= stack.pop();//连乘从栈顶取出的元素
 9             }
10             return result;
11         }

  测试结果:  

1 console.log(Factorial(10));//输出3628800
2 console.log(StackFactorial(10));//输出3628800

  本文的示例代码地址:https://github.com/LJunChina/JavaScript

posted @ 2017-03-12 14:51  有BUG  阅读(560)  评论(2编辑  收藏  举报