JavaScript 中栈的运用操作步骤

 更新时间:2024年11月19日 08:53:03   作者:扰晨  
栈是一种强大的数据结构,在 JavaScript 中有许多实际应用,从表达式求值到函数调用栈,从图的遍历到括号匹配,栈都发挥了重要作用,这篇文章主要介绍了JavaScript中栈的运用,需要的朋友可以参考下

JavaScript 中栈的运用

在 JavaScript 中,栈(Stack)是一种非常有用的数据结构,它遵循后进先出(Last In First Out,LIFO)的原则。在本文中,我们将深入探讨栈的概念以及在 JavaScript 中的实际运用。

一、栈的概念

栈是一种线性数据结构,它只能在一端进行插入(称为入栈或压栈,push)和删除(称为出栈或弹栈,pop)操作。想象一下一摞盘子,你只能从最上面拿盘子(出栈)或者把盘子放在最上面(入栈)。

栈通常具有以下几个基本操作:

  • push(element):将一个元素压入栈顶。
  • pop():弹出栈顶元素并返回它。
  • peek():查看栈顶元素,但不弹出它。
  • isEmpty():判断栈是否为空。

二、在 JavaScript 中实现栈

以下是用 JavaScript 实现一个简单栈的代码:

class Stack {
    constructor() {
        this.items = [];
    }
    push(element) {
        this.items.push(element);
    }
    pop() {
        if (this.isEmpty()) {
            return "Underflow";
        }
        return this.items.pop();
    }
    peek() {
        if (this.isEmpty()) {
            return null;
        }
        return this.items[this.items.length - 1];
    }
    isEmpty() {
        return this.items.length === 0;
    }
    size() {
        return this.items.length;
    }
}

三、栈的实际运用

(一)表达式求值

  • 中缀表达式转后缀表达式在计算机科学中,将中缀表达式转换为后缀表达式是栈的一个重要应用。中缀表达式是我们通常使用的算术表达式形式,如(2 + 3) * 4。后缀表达式则是将运算符放在操作数之后,例如2 3 + 4 *

算法步骤如下:

  • 初始化一个空栈用于存储运算符。
  • 从左到右遍历中缀表达式。
  • 如果遇到操作数,直接输出。
  • 如果遇到左括号,将其压入栈。
  • 如果遇到右括号,弹出栈中的运算符并输出,直到遇到左括号,然后丢弃左括号。
  • 如果遇到运算符,根据其优先级进行处理。如果栈顶运算符的优先级高于或等于当前运算符,则弹出栈顶运算符并输出;否则,将当前运算符压入栈。
  • 遍历结束后,将栈中的剩余运算符依次弹出并输出。

以下是用 JavaScript 实现中缀表达式转后缀表达式的代码:

function infixToPostfix(expression) {
    const stack = new Stack();
    let postfix = "";
    const precedence = {
        '+': 1,
        '-': 1,
        '*': 2,
        '/': 2
    };
    for (let char of expression) {
        if (/[0-9]/.test(char)) {
            postfix += char;
        } else if (char === '(') {
            stack.push(char);
        } else if (char === ')') {
            while (!stack.isEmpty() && stack.peek()!== '(') {
                postfix += stack.pop();
            }
            stack.pop(); // 弹出左括号
        } else {
            while (!stack.isEmpty() && precedence[stack.peek()] >= precedence[char]) {
                postfix += stack.pop();
            }
            stack.push(char);
        }
    }
    while (!stack.isEmpty()) {
        postfix += stack.pop();
    }
    return postfix;
}
  • 后缀表达式求值一旦将中缀表达式转换为后缀表达式,就可以很容易地对后缀表达式进行求值。

算法步骤如下:

  • 从左到右遍历后缀表达式。
  • 如果遇到操作数,将其压入栈。
  • 如果遇到运算符,弹出栈中的两个操作数,进行相应的运算,然后将结果压回栈。
  • 遍历结束后,栈中唯一的元素就是表达式的结果。

以下是用 JavaScript 实现后缀表达式求值的代码:

function evaluatePostfix(postfix) {
    const stack = new Stack();
    for (let char of postfix) {
        if (/[0-9]/.test(char)) {
            stack.push(parseInt(char));
        } else {
            const operand2 = stack.pop();
            const operand1 = stack.pop();
            switch (char) {
                case '+':
                    stack.push(operand1 + operand2);
                    break;
                case '-':
                    stack.push(operand1 - operand2);
                    break;
                case '*':
                    stack.push(operand1 * operand2);
                    break;
                case '/':
                    stack.push(operand1 / operand2);
                    break;
            }
        }
    }
    return stack.pop();
}

(二)函数调用栈

在 JavaScript 中,当一个函数调用另一个函数时,会在内存中创建一个称为调用栈(Call Stack)的结构。调用栈是一种栈数据结构,它用于跟踪函数的调用顺序。

例如:

function functionA() {
    console.log("Inside functionA");
    functionB();
}
function functionB() {
    console.log("Inside functionB");
}
functionA();

functionA被调用时,它的执行上下文被压入调用栈。当functionA调用functionB时,functionB的执行上下文也被压入调用栈。当functionB执行完毕后,它的执行上下文从调用栈中弹出。然后,functionA继续执行,直到它也执行完毕,其执行上下文也从调用栈中弹出。

这种机制确保了函数的正确执行顺序和变量的作用域管理。

(三)深度优先搜索(DFS)

深度优先搜索是一种图遍历算法,它可以使用栈来实现。

以下是用 JavaScript 实现深度优先搜索的代码:

class Graph {
    constructor() {
        this.adjacencyList = {};
    }
    addVertex(vertex) {
        if (!this.adjacencyList[vertex]) {
            this.adjacencyList[vertex] = [];
        }
    }
    addEdge(vertex1, vertex2) {
        this.adjacencyList[vertex1].push(vertex2);
        this.adjacencyList[vertex2].push(vertex1);
    }
    dfs(startVertex) {
        const stack = new Stack();
        const visited = {};
        stack.push(startVertex);
        visited[startVertex] = true;
        while (!stack.isEmpty()) {
            const currentVertex = stack.pop();
            console.log(currentVertex);
            for (let neighbor of this.adjacencyList[currentVertex]) {
                if (!visited[neighbor]) {
                    stack.push(neighbor);
                    visited[neighbor] = true;
                }
            }
        }
    }
}

可以使用以下方式调用:

const graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addVertex('E');
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('B', 'D');
graph.addEdge('C', 'E');
graph.dfs('A');

在这个例子中,深度优先搜索从给定的起始顶点开始,使用栈来存储待访问的顶点。每次从栈中弹出一个顶点,访问它,并将其未访问过的邻居顶点压入栈。

(四)括号匹配

检查一个字符串中的括号是否匹配是栈的另一个常见应用。

算法步骤如下:

  • 初始化一个空栈。
  • 遍历字符串中的每个字符。
  • 如果遇到左括号,将其压入栈。
  • 如果遇到右括号,检查栈是否为空。如果为空,说明右括号没有匹配的左括号,返回 false。如果栈不为空,弹出栈顶元素,检查弹出的左括号是否与当前右括号匹配。如果不匹配,返回 false。
  • 遍历结束后,如果栈为空,说明所有括号都匹配,返回 true;否则,返回 false。

以下是用 JavaScript 实现括号匹配的代码:

function isBalanced(str) {
    const stack = new Stack();
    for (let char of str) {
        if (char === '(' || char === '[' || char === '{') {
            stack.push(char);
        } else if (char === ')' || char === ']' || char === '}') {
            if (stack.isEmpty()) {
                return false;
            }
            const top = stack.pop();
            if ((char === ')' && top!== '(') || (char === ']' && top!== '[') || (char === '}' && top!== '{')) {
                return false;
            }
        }
    }
    return stack.isEmpty();
}

四、总结

栈是一种强大的数据结构,在 JavaScript 中有许多实际应用。从表达式求值到函数调用栈,从图的遍历到括号匹配,栈都发挥了重要作用。理解栈的概念和操作,以及如何在 JavaScript 中实现和应用栈,对于编写高效的代码和解决各种编程问题非常有帮助。

到此这篇关于JavaScript 中栈的运用的文章就介绍到这了,更多相关js栈的运用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

到此这篇关于JavaScript 中栈的运用操作步骤的文章就介绍到这了,更多相关js栈的运用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Bootstrap的图片轮播示例代码

    Bootstrap的图片轮播示例代码

    Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的。本文给大家分享Bootstrap的图片轮播示例代码,小伙伴们快来围观吧。
    2015-08-08
  • 详解JavaScript 中getElementsByName在IE中的注意事项

    详解JavaScript 中getElementsByName在IE中的注意事项

    这篇文章主要介绍了详解JavaScript 中getElementsByName在IE中的注意事项的相关资料,需要的朋友可以参考下
    2017-02-02
  • 前端语法高亮插件Prism.js使用详细教程

    前端语法高亮插件Prism.js使用详细教程

    最近项目有代码高亮的需求,这边是选用Prism.js来进行代码高亮,Prism是一款轻量级、可扩展的语法高亮器,根据现代 Web 标准构建,应用广泛,这篇文章主要给大家介绍了关于前端语法高亮插件Prism.js使用详细教程的相关资料,需要的朋友可以参考下
    2024-05-05
  • 原生js实现淘宝放大镜效果

    原生js实现淘宝放大镜效果

    这篇文章主要为大家详细介绍了原生js实现放大镜效果,制作一个类似于淘宝的放大镜效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • 纯js模仿windows系统日历

    纯js模仿windows系统日历

    本文主要介绍了纯js模仿windows系统日历的思路与实现方法。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 如何在TypeScript 中实现接口的类

    如何在TypeScript 中实现接口的类

    这篇文章主要介绍了TypeScript 中实现接口的类,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 8种现代JavaScript响应式模式小结

    8种现代JavaScript响应式模式小结

    响应式的本质是关于系统如何对数据变化做出反应,并且存在不同类型的响应式,本文就来介绍8种现代JavaScript响应式模式小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • JavaScript中三种非破坏性处理数组的方法比较

    JavaScript中三种非破坏性处理数组的方法比较

    在这篇文章中,我们将会探索处理数组的三种方法:for…of循环、数组方法.reduce()和数组方法.flatMap(),文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-06-06
  • javascript使用正则表达式检测IP地址

    javascript使用正则表达式检测IP地址

    这篇文章主要介绍了javascript使用正则表达式检测IP地址的方法,需要的朋友可以参考下
    2014-12-12
  • js实现使用输入input和改变change事件模拟手动输入

    js实现使用输入input和改变change事件模拟手动输入

    聚焦于JavaScript中的输入模拟技术,本指南将带你探索如何使用input和change事件来创造逼真的手动输入效果,通过简单的代码实现,你将掌握这一实用的技巧,为你的Web应用增添交互的乐趣,需要的朋友可以参考下
    2024-03-03

最新评论