1、栈的定义
栈是一种特殊的线性表,仅能够在栈顶进行操作,有着先进后出(后进先出)的特性,下面这张图展示里栈的工作特点:
2、栈有以下几个方法
- push():添加一个元素到栈顶
- pop() : 弹出栈顶元素
- top() : 返回栈顶元素
- isEmpty() : 判断栈是否为空
- size() : 返回栈里元素个数
- clear() : 清空栈
function Stack(){
var items = [];
this.push = function(item){
items.push(item);
}
//删除并返回数组的最后一个元素
this.pop = function(){
return items.pop();
}
this.top = function(){
return items[items.length - 1]
}
this.isEmpty = function(){
return items.length === 0
}
this.size = function(){
return items.length
}
this.clear = function(){
items = [];
}
}复制代码
3、栈的应用练习
1、判断字符串里的括号是否合法
思路分析:
遇到左括号压入栈
遇到右括号,判断栈里是否为空
为空说明没有左括号与之对应,缺少左括号,字符串括号不合法
不为空则把栈顶元素移除,这对括号就抵消了
function is_leagl_brackets(str){
var stack = new Stack();
for(var i=0;i<str.length;i++){
var item = str[i];
// 遇到左括号压入栈
if(item === '('){
stack.push(item);
//遇到右括号判断是否为空
}else if(item === ')'){
if(stack.isEmpty()){
//为空则不合法
return false;
}else{
//不为空则移除栈顶元素,一对括号抵消
stack.pop();
}
}
}
return stack.isEmpty();
}复制代码
2、计算逆波兰表达式
逆波兰表达式,也叫后缀表达式,它将复杂表达式转化为可以依靠简单的操作得到计算结果的表达式,例如 (a+b)*(c+d) => ab+cd+*
["4", "13", "5", "/", "+"] 等价于(4 + (13 / 5)) = 6 ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] 等价于((10 * (6 / ((9 + 3) * -11))) + 17) + 5
思路:
如果元素不是['+','-','*','/']中的某一个,就压入栈
如果元素是['+','-','*','/']中的一个,则从栈里连续弹出两个元素,并对这两个元素进行计算,将计算结果压入栈中
function calc_exp(arr){
var stack = new Stack();
for(var i=0;i<arr.length;i++){
var item = arr[i];
//判断是数字还是符号
if(['+','-','*','/'].indexOf(item) >= 0){
//是符号,则从栈里分别弹出两个元素进行计算
var value_1 = stack.pop();
var value_2 = stack.pop();
var exp_str = value_2 + item + value_1;
var res = parseInt(eval(exp_str));
//将计算结果压入栈中
stack.push(res.toString());
}else{
//是数字,则压入栈中
stack.push(item);
}
}
//返回栈里唯一一个元素,计算结果
return stack.pop();
}复制代码
3、实现一个有min方法的栈
思路:
两个栈,一个存储数据 data_stack,一个存储栈里最小数据min_stack
data_stack直接存储数据
min_stack先考虑边界问题,里面为空,push进来的数据则是最小值
如果push进来的数据比min_stack栈顶元素小,则直接push,否则把原来的栈顶元素再push一遍
function MinStack(){
//普通栈
var data_stack = new Stack();
//专门存储最小值
var min_stack = new Stack();
//push的时候,两个栈都要操作
this.push = function(item){
data_stack.push(item);
//如果栈内为空,直接放入,如果item小于栈顶元素,放入其中,以保证栈顶元素为最小值
if(min_stack.isEmpty() || item < min_stack.top()){
min_stack.push(item);
}else{
//如果item大于栈顶元素,则把栈顶元素重新放入一次
//以保证min_stack个数和data_stack个数相同
min_stack.push(min_stack.top());
}
};
//pop的时候,两个栈都pop
this.pop = function(){
data_stack.pop();
min_stack.pop();
}
//栈顶元素总是最小值
this.min = function(){
return min_stack.top();
}
}复制代码