栈是一种遵从后进先出(LIFO)原则的有序集合。什么是栈呢?在这里可以脑补一下一摞书或者家里的一摞盘子,或者干脆可以这么想,把数组塞进桶里就成栈了,新添加的或者待添加的元素都在靠近出口位置,也就是我们常说的栈顶,而另外一端桶底(封闭的那头)称为栈底。
一、栈的创建
可以创建一个类来表示栈,先声明一个类:
function Stack(){
//各种属性和方法的声明
}
接着,我们考虑一下,用什么来保存栈里的元素呢?既然刚刚说栈就是把数组塞进桶里,那么我们自然而然地可以用数组来保存栈里的元素,声明一个数组:
var items = [];
再来,思考一下,还需要为栈声明什么方法?
看这里!!!
push(element):添加新元素进栈。
pop():移除栈顶的元素,同时返回被移出的元素。
peek():返回栈顶的元素,但不对栈进行任何的修改、操作。
isEmpty():判断栈是否为空,为空则返回true,不为空则返回false。
clear():清空栈里的所有元素。
size():返回栈里的元素个数。
首先实现push方法。这个方法负责往栈里添加新的元素,这个方法只能把新元素添加到栈顶,这个十分重要。代码如下:
this.push=function(element){
items.push(element);
};
接着来实现pop方法,这个方法是用来移除栈顶的元素,必须遵守LIFO(先进后出)原则,这时候pop()方法派上大用处了:
this.pop=function(){
return items.pop();
};
只能用push和pop方法添加和删除元素,这样我们的栈就遵从LIFO的原则了。这就是加在数组上的“桶身”,限制元素从其它地方蹦出来,哈哈!
现在可以实现以下其它的辅助方法了。比如想知道栈顶的元素到底是什么,可以用peek方法,其作用就是返回栈顶的元素,但是不进行操作哦!因为类内部是数组保存元素,所以可以通过访问数组的最后一个元素来获取栈顶的元素,其下标为length-1:
this.peek=function(){
return items[items.length-1];
};
下一个是isEmpty方法:
this.isEmpty=function(){
return items.length == 0;
};
再来实现一下clear方法,用于清空栈内所有的元素:
this.clear=function(){
items=[];
};
在这里也可以遍历数组移除元素来达到清空的目的,但是明显麻烦不少。
最后来实现一下size方法,返回栈的长度:
this.size=function(){
return items.length;
};
来看一下完整的代码:
function Stack(){
var items=[];
//添加一个新元素到栈顶
this.push=function(element){
items.push(element);
};
//移除栈顶的元素并返回被移除的值
this.pop=function(){
return items.pop();
};
//返回栈顶的元素,但不做任何处理
this.peek=function(){
return items[items.length-1];
};
//判断栈是否为空
this.isEmpty=function(){
return items.length == 0;
};
//清空栈内所有元素
this.clear=function(){
items=[];
};
//返回栈内的元素个数
this.size=function(){
return items.length;
};
//打印输出栈内元素
this.print=function(){
console.log(items.toString());
};
}
二、栈的小应用—十进制转二进制
function divideBy2(number){
var remStack = new Stack(),
rem,
binaryString='';
while(number>0){
rem=Math.floor(number%2);
//余数进栈
remStack.push(rem);
number=Math.floor(number/2);
}
while(!remStack.isEmpty()){
binaryString+=remStack.pop().toString();
}
return binaryString;
};