js实现栈与简单应用

184 阅读2分钟

概念

  • 栈又称为下压栈,是一种基于后进先出(LIFO)策略的集合类型。
  • 举个例子:桌子上放着的一叠文件,当收到新的文件时新文件放到这叠文件的顶部,当你阅读文件时,从这叠文件的最顶端开始拿取文件进行阅读,就是栈的简单模型。

实现栈的基本功能:

  • push: 添加一个新元素到栈顶
  • pop: 移除栈顶元素
  • peek: 获取栈顶元素
  • isEmpty: 判断栈是否为空
  • clear: 清空栈内元素
  • size: 获取栈的长度

ES5版本 构造函数和原型实现栈

function InitStack () {
    this.stack = []
}

InitStack.prototype.push = function (item) {
    this.stack.push(item)
}
InitStack.prototype.pop = function () {
    this.stack.pop()
}
InitStack.prototype.peek = function() {
    return this.stack[this.stack.length - 1]
}
InitStack.prototype.size = function() {
    return this.stack.length
}
InitStack.prototype.print = functon() {
    return this.stack
}
var myStack = new InitStack()

myStack.push(1)
console.log('stack', myStack.print())

ES6版本 class类实现栈

class InitStack {
    constructor() {
        this.stack = []
    }
    push(item) {
        this.stack.push(item)
    }
    pop() {
        this.stack.pop()
    }
    peek() {
        return this.stack(this.stack.length - 1)
    }
    clear() {
        return this.stack = []
    }
    size() {
        return this.stack.length
    }
    print() {
        return this.stack
    }
}
let stack = new InitStack()

stack.push(1)
stack.push(2)
console.log(stack.print())

栈的简单应用

  • 实现一个简单表达式求值 (1 + ((2 + 3) * (4 * 5)))
  • 实现原理:新建两个栈,用来存储操作符和,从左到右遍历表达式
    • 忽略左括号
    • 遇到操作符,将操作符存入操作符栈
    • 遇到运算符,将运算符存入运算符栈
    • 遇到右括号,弹出一个运算符,弹出2个操作数,并将计算结果存入操作符栈
class InitStack {
    constructor() {
      this.stack = []
    }

    push(item) {
      this.stack.push(item)
    }
    pop() {
      this.stack.pop()
    }
    peek() {
      return this.stack[this.stack.length - 1]
    }
    clear() {
      return this.stack = []
    }
    size() {
      return this.stack.length
    }
    print() {
      return this.stack
    }
 }
 function process () {
    let numStack = new InitStack()  //操作数栈
    let signStack = new InitStack() //运算符栈

    let expr = document.getElementById('code').value 
    expr = expr.replace(/\s+/g, "")
    exprList = expr.split("")
    let result = null
    exprList.forEach((item, index) => {
      if (/[0-9]/.test(item)) {
        numStack.push(Number(item))
      } else if (/[+\/\-*]/g.test(item)) {
        signStack.push(item)
      } 
      else if (item === ')'){
        let num1 = numStack.peek()
        numStack.pop()  
        let num2 = numStack.peek()
        numStack.pop()
        let sign = signStack.peek()
        signStack.pop()
        if (sign === '+') {
          result = num2 + num1
        } else if (sign === '-') {
          result = num2 - num1
        } else if (sign === '*') {
          result = num2 * num1
        } else if (sign === '/') {
          result = num2 / num1
        }
        if (index === exprList.length - 1) {
          console.log(result)
        } else {
          numStack.push(result)
        }
      }
    })
  }