JavaScript-栈

110 阅读3分钟

来源:【程序员成功】公众号

栈--数组篇

引入

(你遇到的使用栈的场景有哪些?)

生活中去饭堂打饭,我们需要自己去拿托盘,托盘的摆放是层叠的,最先放在下面的托盘反而是最后被拿起来的

//个人认为这是一个非常贴近生活的形容栈的一个例子

什么是栈?

栈是一种数据结构,其本质是一个数组,只不过栈在数组的基础上加了一些限制 (这可谓是非常粗浅的理解了😁)

栈长什么样?

结合刚说的栈的本质是数组,所以说栈其实就是由一长串字符串组成的一条长龙

栈的规则是什么?

唯一与数组不一样的就是不能随心所欲的插队,栈的排队方式有着自己的规则

特性:后进先出(Last in first out),也就是说栈是一种遵从后进先出原则的有序集合

后进先出,很好理解吧,就是最先进去的,最后出来,最后进去的,反而最先出来

栈.png

如何使用

  1. 创建一个栈
  2. 常用方法
  3. 使用
//使用ES6的Class关键字
class Stack{
    constructor(){
        //用一个lists数组保存栈的数据
        this.lists = [] //默认空数组
    }

    //常用方法
    /*
    1:入栈
    2:出栈
    3:清空栈
    4:判断栈是否有元素
    5:栈的元素数量
    6:返回栈顶元素
    */
   push(item){
       this.lists.push(item)
   }

   pop(){
       //弹出栈顶元素
       this.lists.pop()
   }

   clear(){
       this.lists = []
   }

   isEmpty(){
      return this.lists.length == 0
   }

   size(){
       return this.lists.length
   }

   peek(){
        this.lists[this.lists.length - 1]
   }

}

const s = new Stack()
console.log(s.isEmpty());
s.push('河源')
s.push('东莞')
console.log(s.size());
s.pop('河源')
console.log(s.size());
console.log(s.isEmpty());

使用数组形式的栈有很大的弊端,数组的操作本质都是要遍历数组,直到查到目标,如果当数组的数据非常多时,查询的效率就会很低,加上数组会保证元素的排列顺序,因此也会占用更多的内存

为了解决上述问题,引入JavaScript对象

栈--JavaScript对象篇

直接上代码

class Stack{
    constructor(){
        //count表示栈元素长度
        this.count = 0;
        //保存栈的元素
        this.lists = {};
    }

    //同数组篇的方法是一样的
    push(value){
        this.lists[this.count] = value
        this.count++
    }

    pop(){
        if(this.isEmpty()){
            return undefined
        }
        this.count--
        //找到栈顶的元素,先用一个变量把值存起来
        let list = this.lists[this.count]
        //然后再删除
        delete this.lists[this.count]
        //最后返回那个被删除的元素
        return list
    }

    isEmpty(){
        return this.count == 0
    }

    size(){
        return this.count
    }

    clear(){
        this.count = 0;
        this.lists = {}
    }

    peek(){
        if(this.isEmpty()){
            return undefined
        }
        return this.lists[this.count-1]
    }

    //实现toString方法
    /*
    数组提供了默认的toString方法,当想用字符串的形式展现数组时,数组可以直接调用toString方法
    但是对象的toString方法返回的都是[object object],
    所以想要实现字符串形式展现,需要自己写一个toString方法,按照数组的格式返回
    ES6给我们提供了对象直接转成数组的方式
    */
   toString(){
       //对象转化为数组,通过调用Object.value()
       let arr = Object.values(this.lists)
       return arr.toString()
   }
}

let s = new Stack()
s.push('上海')
s.push('北京')
s.push('河源')
s.push('东莞')
console.log(s.size());
console.log(s);
console.log(s.isEmpty());
s.pop()
console.log(s);
console.log(s.toString());

运行截图: 运行.PNG

力扣 20题:有效括号

//解法一
var isValid = function(s){
    const stack = [];
    for(let i = 0; i < s.length; i++){
        const x = s[i]
        if(x === "(" || x === "[" || x === "{"){
            //入栈
            stack.push(x)
        } else{
            if(stack.length == 0){
                return false
            }
            //去除栈顶元素与x作比较
            const top = stack[stack.length-1]
            if(top === "(" && x === ")" ||top === "{" && x === "}" || top === "[" && x === "]" ){
                stack.pop()
            } else{
                return false
            }
        }
    }
    return stack.length == 0
};
//解法二:Map
var isValid = function(s){
    //先判断s的长度是否为偶数,若为奇数,则说明一定会有一个括号未匹配
    if(s.length % 2 === 1){
        return false;
    }
    const map = new Map([
        [")","("],
        ["]","["],
        ["}","{"]
    ])
    const stack = []

    for(let x of s){
        if(map.has(x)){
            if(!stack.length || stack[stack.length-1] !== map.get(x)){
                return false
            }
            stack.pop()
        } else{
            stack.push(x)
        }
    }
    return !stack.length
}