JS语言中,栈与队列其实都是数组,只是调用方法的不同使其呈现出栈与队列的特质罢了。
栈
function Stack(){
//用数组来模拟栈
this.items = [];
this.push = function(element){
this.items.push(element);
};
this.pop = function(){
return this.items.pop();
};
//返回栈顶元素,可以用数组长度实现
this.peek = function(){
return this.items[this.items.length-1];
};
//确定栈是否为空
this.isAmpty = function(){
return this.items.length === 0;
};
//清空栈中所有内容
this.clear = function(){
this.items = [];
};
//返回栈的长度
this.size = function(){
return this.items.length;
};
//以字符串显式栈中所有内容
this.print = function(){
console.log(this.items.toString());
//console.log(items.join());//与上面等效
//toString()返回值与没有参数的 join() 方法返回的字符串相同,数组中的元素之间用逗号分隔。
}
}
栈的实际应用:十进制转二进制。主要思想是:用这个要转化的数不停的除2取余,并且用商来重复之前的操作,直至商为0。
function divideBy2(decNumber){
var remainder = 0,binaryString = '';
var stack = new Stack();
while(decNumber>0){
remainder = Math.floor(decNumber%2);
stack.push(remainder);
decNumber = Math.floor(decNumber/2);
};
while(!stack.isAmpty()){
binaryString += stack.pop();
};
return binaryString;
}
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
分析:借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
function IsPopOrder(pushV, popV)
{
var stack = [],idx = 0;
for(var i=0; i<pushV.length; i++){
stack.push(pushV[i]);
while(stack.length && stack[stack.length-1]===popV[idx]){
stack.pop();
idx++;
}
}
return stack.length === 0;
}
队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
分析:入队操作即在stack1上执行入栈;出队操作时,若stack2不为空,则在stack2上执行出栈, 若stack2为空,则将stack1内的元素依次全部压入stack2内。这样入队出队操作都为O(1)的复杂度。
var stack1 = [],stack2 = [];
function push(node)
{
stack1.push(node);
}
function pop()
{
// 只需要入队用一个栈,出队用另一个栈
if(stack2.length===0){//先判断2是否为空
while(stack1.length!==0){//如果为空就将1的弹给它
stack2.push(stack1.pop());
}
}
return stack2.pop();//在第二个栈上执行出栈
}