概述
栈是一种特殊的线性表,仅能够在栈顶进行操作,有着先进后出(后进先出)的特性。
如何实现一个栈
从数据存储的角度看,实现栈的方式有2种:一种是以数组作基础,一种是以链表作基础。
定义一个类 Stack,实现以下几个函数:
- push 添加一个元素到栈顶
- pop 弹出栈顶元素
- top 返回栈顶元素(不是弹出)
- isEmpty 判断栈是否为空
- size 返回栈里元素的个数
- clear 清空栈
以数组实现一个栈
function Stack(){
var items = []
// 向栈压入1个元素
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 = []
}
}
以链表实现一个栈
LinkList 链表的实现,传送门
function Stack(){
var linklist = new LinkList()
// 从栈顶添加元素
this.push = function(item){
linklist.append(item)
}
// 弹出栈顶元素
this.pop = function(){
return linklist.removeTail()
}
// 返回栈顶元素
this.top = function(){
return linklist.tail()
}
// 返回栈的大小
this.size = function(){
return linklist.length()
}
// 判断是否为空
this.isEmpty = function(){
return linklist.isEmpty()
}
// 清空栈
this.clear = function(){
linklist.clear()
}
}
题目练习
合法括号
下面字符串中包含小括号,编写一个函数判断字符串中的括号是否合法。合法条件是:括号成对出现。
示例:
sdf(ds(ew(we)rw)rwqq)qwewe 合法
(sd(qwqw)sd(sd)) 合法
()()sd()(sd()fw))( 不合法
思路
- 遍历字符串的每个字符。
- 遇到左括号,就把左括号压入栈中。
- 遇到右括号,先判断栈是否为空,为空说明没有左括号与之对应则字符串括号不合法。如果栈不为空,则把栈顶元素移除,将这对括号抵消掉。
- 当遍历结束后,如果栈为空,就说明所有的左括号都抵消掉了,如果栈里还有元素,则说明缺少右括号,字符括号不合法。
代码:
function isLegalBrackets(str){
var stack = new Stack()
for(var i=0, len=str.length; i< len; i++){
var item = str[i]
if(item === '('){
stack.push(item)
}else if(item === ')'){
if(stack.isEmpty()){
return false
}else{
stack.pop()
}
}
}
return stack.size() === 0
}
console.log('sdf(ds(ew(we)rw)rwqq)qwewe')
console.log('(sd(qwqw)sd(sd))')
console.log('()()sd()(sd()fw))(')
计算逆波兰表达式
逆波兰表达式(后缀表达式),它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(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
思路
- 遍历数组,进行分类。
- 如果元素不是 + - * / 中的某一个,就压入栈中。
- 如果元素是 + - * / 中的某一个,则从栈里连续弹出2个元素,并对这2个元素进行计算,将计算结果压入栈中。
- 遍历结束后,栈只有一个元素,这个元素就是整个表达式的计算结果。
代码
function calcExp(exp){
var stack = new Stack()
for(var i=0, len= exp.length; i < len; i++){
var item = exp[i]
if(['+','-','*','/'].includes(item)){
// 栈顶弹出2个元素
var value1 = stack.pop()
var value2 = stack.pop()
// 拼成表达式
var expStr = value2 + item + value1
// 计算并取整
var result = parseInt(eval(expStr))
// 将计算结果压入栈中
stack.push(result.toString())
}else{
stack.push(item)
}
}
return stack.pop()
}
console.log(["4","13","5","/","+"])