栈是一种“先进后出”的数据结构。好比向一个盒子中放东西,先放进去的在下面,后放进去的在上面。拿出来的时候要先把上面的拿出,才能拿下面的。
(网上找的图。。。)
栈的实现–基于JavaScript数组
栈的操作基本的就入栈和出栈两种。下面基于JavaScript的数组来实现一个栈。
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 = [];
}
}
栈的使用
var stack = new Stack();
//入栈2个数据 'a'和'b' 'a'先入,所以'a'在下面
stack.push('a');
stack.push('b');
console.log(stack.size());//2 有2个数据
console.log(stack.top());//'b' b在栈顶
console.log(stack.isEmpty());//false
stack.pop();//出栈
console.log(stack.size());// 1 'b'出栈了 只剩'a'
stack.clear();//清空栈
console.log(stack.isEmpty());//true 栈已经清空了
栈的应用练习
通过两个练习题来加深对栈的理解。
1、合法括号
题目:下面的字符串中包含小括号,编写一个函数判断字符串中的括号是否合法。(括号是否成对出现)。
sdg(dsf(sdfsd(dfgs))dsadf) 合法
sdg(dsf(sdfsddfgs))dsadf) 不合法
思路:
- 使用for循环遍历字符串。
- 遇到左括号,就把左括号压入栈中。
- 遇到右括号,判断栈是否为空,为空则说明没有左括号与之对应,缺少左括号,字符串不合法。 不为空,则把栈顶的元素移除,这对括号就抵消了。
- 当for循环结束后,如果栈是空的,则说明左右括号都抵消了,字符串合法。如果栈里面还有元素,则说明缺少右括号,字符串不合法。
// 判断字符串里的括号是否合法
function is_leagl_brackets(str){
var stack = new Stack();
for (let i = 0; i < str.length; i++) {
let item = str[i];
// 遇到左括号入栈
if(item=='('){
stack.push(item)
}else if(item==')'){
// 遇到右括号,判断栈是否为空
if(stack.isEmpty()){
return false;
}else{
stack.pop();//弹出
}
}
}
// 如果栈为空,说名字符串括号合法
return stack.isEmpty();
}
console.log(is_leagl_brackets('sdg(dsf(sdfsd(dfgs))dsadf)'));//true
console.log(is_leagl_brackets('sdg(dsf(sdfsddfgs))dsadf)'));//false
2、逆波兰表达式(后缀表达式)
题目:编写函数实现逆波兰表达式计算。
['4','3','+'] 等价于 4+3
['4','6','2','+','*'] 等价于 4*(6+2)
思路:
1、遍历数组 判断元素是不是+ - * /中的某一个 如果不是 就入栈(运算符不入栈)
2、遇到运算符 连续两次出栈 将这两个数计算 得到结果后入栈
function calc_exp(exp){
let stack = new Stack();
for (let i = 0; i < exp.length; i++) {
let item = exp[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();
}
console.log(calc_exp(['4','6','2','+','*']));//32