探索 Javascript 数据结构:深入理解栈

前言

在计算机科学中,栈是一种极其重要的数据结构,其特性是遵循"先进后出"(FILO)原则。尽管 JavaScript 并未内置栈(Stack)数据结构,但我们可以通过数组来模拟实现栈的全部功能。

栈的基本概念

栈的主要特点是"先进后出"(FILO),栈只能对栈顶进行操作,不关心内部的元素状态,添加的元素会放在栈顶,删除的元素也会从栈顶位置开始,意味着最后进入的元素会被首先取出。

202003070853041.png

202003070853041.png

栈最重要的特征是只允许从一端操作数据,栈就像一叠书,或者盘子,每次只能从最上边拿,往最上边放。在栈操作中,入栈(push)和出栈(pop)的时间复杂度为 O(1),而查找(search)的时间复杂度为 O(n)。

以下是栈的基本操作:

  • 入栈(push):将元素添加到栈顶。

  • 出栈(pop):移除并返回栈顶的元素。

  • 查看栈顶元素(peek):返回栈顶的元素,不改变栈的状态。

  • 查找元素(search):返回指定元素在栈中的位置。

  • 清空栈(clear):移除栈中的所有元素。

用 Javascript 实现一个栈类

我们可以封装一个Stack类,通过使用数组来模拟实现栈,下面是代码实现:

class Stack {
    constructor() {
        this.items = []
    }

    // 入栈
    push(element) {
        this.items[this.items.length] = element
    }

    // 出栈
    pop() {
        if (this.isEmpty()) {
            return 'Stack is empty'
        }
        return this.items.splice(this.items.length - 1, 1)
    }

    // 查看栈顶元素,若栈顶元素为空返回 'Stack is empty'
    peek() {
        if (this.isEmpty()) {
            return 'Stack is empty'
        }
        return this.items[this.items.length - 1]
    }

    // 判断栈是否为空
    isEmpty() {
        return this.items.length === 0
    }

    // 清空栈
    clear() {
        this.items = []
    }
 
    // 返回栈顶的大小
    size() {
        return this.items.length
    }
}

在这个 Stack 类中,我们定义了 push、pop、peek、isEmpty、clear 和 size 等方法,它们分别对应栈的基本操作。我们可以通过实例化这个类,来创建一个可以进行各种操作的栈。

// 创建栈
const stack = new Stack();
  
// 入栈
stack.push(1);
stack.push(2);
stack.push(3);

// 出栈
console.log(stack.pop());  // 3

// 查看栈顶元素
console.log(stack.peek()); // 2

// 判断栈是否为空
console.log(stack.isEmpty()); // false

// 查看栈长度
console.log(stack.size()); // 2

栈的应用:有效的括号

题目:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。

  • 左括号必须以正确的顺序闭合。

  • 每个右括号都有一个对应的相同类型的左括号。

解题思路: 我们可以利用栈来解决这个问题。思路是这样的:遍历字符串,遇到左括号就入栈,遇到右括号就检查它是否与栈顶元素匹配。如果匹配,就弹出栈顶元素;如果不匹配,就返回 false。最后,检查栈是否为空。如果为空,说明所有的括号都正确匹配,返回 true;如果不为空,说明有未匹配的括号,返回 false。

题解:

var isValid = function(s) {
    const n = s.length;
    if (n % 2 === 1) {
        return false;
    }

    const pairs = new Map([
        [')', '('],
        [']', '['],
        ['}', '{']
    ]);

    const stk = [];
    for (let ch of s){
        if (pairs.has(ch)) {
            if (!stk.length || stk[stk.length - 1] !== pairs.get(ch)) {
                return false;
            }
            stk.pop();
        } else {
            stk.push(ch);
        }
    };
    return !stk.length;
};

isValid('()[]{}') // true

这个例子展示了如何使用栈来解决实际问题,通过简单的入栈和出栈操作,我们可以有效地检查括号是否匹配。

结语

栈是一种非常实用的数据结构,它在很多计算机科学的领域都有应用,比如编译器的语法分析、操作系统的内存管理、浏览器的前进和后退功能、函数调用等。通过学习和理解栈,我们可以更好地理解计算机科学的基本原理,也可以提升我们的编程逻辑能力。希望通过这篇文章,你能对栈有更深的理解和应用。

才疏学浅,如有讲述不清之处,还请指正,共同进步。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值