”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解堆栈数据结构:在 JavaScript 中实现堆栈的分步指南

了解堆栈数据结构:在 JavaScript 中实现堆栈的分步指南

发布于2024-11-17
浏览:568

堆栈是一种简单的线性数据结构,其工作原理就像一堆盘子?️。它遵循后进先出 (LIFO) 原则。将其视为一堆盘子:您只能添加或删除堆顶部的盘子。

为了更好的理解栈,让我们来一次短暂的想象之旅吧?.
想象一下您在一家高档餐厅??️,厨房工作人员正在为忙碌的夜晚做准备??‍?。在餐具区,有一大堆盘子等待使用。当食客到来、订单纷至沓来时,工作人员会从最上面的盘子中取出盘子。当添加干净的盘子时,它们会直接放在上面。这个简单的系统确保了位于堆栈底部的放置时间最长的盘子最后被使用,而顶部刚清洁过的盘子首先被使用✨。

Understanding Stack Data Structure: A Step-by-Step Guide to Implementing Stack in JavaScript

本质上,这就是堆栈数据结构的工作原理。堆栈是一种遵循后进先出 (LIFO) 原则的线性数据结构。就像我们的一堆盘子一样,添加到堆栈中的最后一个项目是第一个被删除的项目。

目录

在这个关于堆栈数据结构的综合教程中,我们将通过简单、适合初学者的方法探索以下主题:

  1. 什么是堆栈?
  2. 使用堆栈的优点和缺点
  3. 堆栈的实际应用
  4. 堆栈上的关键操作
  5. JavaScript 中的堆栈实现
  6. 结论


你准备好了吗?让我们深入探讨

Understanding Stack Data Structure: A Step-by-Step Guide to Implementing Stack in JavaScript

什么是堆栈?

堆栈是一种遵循后进先出(LIFO)原则的线性数据结构。这意味着最后添加到堆栈的元素将是第一个被删除的元素。将其想象为一摞书:您只能从书堆顶部添加或删除书籍。

使用堆栈的优点和缺点

在我们继续流程并编写一些代码之前,了解在哪里以及在哪里不使用堆栈是很有帮助的。下表详细给出了堆栈的明确优缺点。

优点 缺点
简单易实现 访问受限(只有顶部元素可以直接访问)
高效的后进先出 (LIFO) 操作 不适合元素的随机访问
入栈和出栈操作的恒定时间 O(1) 如果管理不当可能导致堆栈溢出
对于跟踪算法中的状态很有用(例如深度优先搜索) 不适合搜索或访问任意元素
帮助内存管理(例如,编程语言中的调用堆栈) 某些实现中的固定大小(基于数组的堆栈)
用于反转数据 可能需要在动态实现中调整大小,这可能成本高昂
自然支持递归算法 对于需要频繁遍历的大型数据集效率不高
帮助表达式求值和语法解析 如果在空堆栈上调用弹出操作,则可能发生下溢
在软件中的撤消机制中很有用 与更复杂的数据结构相比,功能有限
对于某些类型的数据组织(例如浏览器历史记录)有效 不适合需要类队列 (FIFO) 行为的问题

堆栈上的关键操作

可以在堆栈上执行的基本操作是:

  1. push():将一个元素添加到栈顶。
  2. pop():从堆栈中删除最顶层的元素。
  3. peek():返回栈顶元素,但不删除它。
  4. isEmpty():检查堆栈是否为空。
  5. size():返回栈中元素的数量。

堆栈的实际应用

堆栈在计算机科学和软件开发中无处不在。以下是一些常见的应用:

  1. 撤消功能:在文本编辑器或图形设计软件中,每个操作都被推入堆栈。当您点击“撤消”时,最近的操作将从堆栈中弹出并反转。

  2. 浏览器历史记录:当您访问新页面时,它将被推送到堆栈上。 “后退”按钮将当前页面从堆栈中弹出,显示上一页。

  3. 函数调用堆栈:在编程语言中,函数调用是使用堆栈来管理的。当一个函数被调用时,它被压入调用栈。当它返回时,它会弹出。

  4. 表达式计算:堆栈用于计算算术表达式,特别是后缀表示法的表达式。

  5. 回溯算法:在解决迷宫或解谜等问题中,堆栈可以跟踪所采取的路径,以便在需要时轻松回溯。

JavaScript 中的堆栈实现

现在,让我们用 JavaScript 实现一个 Stack。重要的是要知道在 JavaScript 中实现堆栈有不同的方法。实现堆栈的常见方法之一是使用数组,另一种方法是使用链表。在本文中,我们将使用链表(单链表)实现堆栈。

使用链表实现堆栈

我希望你还记得链表是如何工作的吗?您可能需要查看我们本系列之前的一篇文章中的链表实现。

现在,让我们开始使用单链表实现我们的堆栈。我们可以?

Understanding Stack Data Structure: A Step-by-Step Guide to Implementing Stack in JavaScript

首先,我们将创建一个 Node 类来表示我们的堆栈单个项目。

class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

然后,我们将创建一个 Stack 类来表示我们的堆栈。

class Stack {
  constructor() {
    this.top = null;
    this.size = 0;
  }

  // Stack Operations will be implemented here ?
}

推送操作

push操作将一个新元素添加到栈顶。它创建一个新的 StackNode,将其下一个指针设置为当前顶部,然后更新顶部以指向这个新节点。最后,它增加大小。

  // Push element to the top of the stack
  push(element) {
    const newNode = new Node(element);
    newNode.next = this.top;
    this.top = newNode;
    this.size  ;
  }

流行操作

出栈操作从堆栈中删除最顶层的元素。它首先检查堆栈是否为空。如果是,则返回错误消息。否则,它删除顶部元素,更新顶部指针到下一个节点,并减少大小。最后,它返回被删除的元素。

  // Remove and return the top element
  pop() {
    if (this.isEmpty()) {
      return "Stack is empty";
    }
    const poppedElement = this.top.data;
    this.top = this.top.next;
    this.size--;
    return poppedElement;
  }

窥视操作

peek 操作返回顶部元素而不删除它。它首先检查堆栈是否为空。如果是,则返回错误消息。否则,返回顶部元素的数据。

  // Return the top element without removing it
  peek() {
    if (this.isEmpty()) {
      return "Stack is empty";
    }
    return this.top.data;
  }

isEmpty操作

isEmpty 操作检查堆栈是否为空。如果堆栈为空则返回 true,否则返回 false。

  // Check if the stack is empty
  isEmpty() {
    return this.size === 0;
  }

获取大小操作

getSize操作返回堆栈的大小。它返回堆栈中元素的数量。

  // Return the size of the stack
  getSize() {
    return this.size;
  }

打印操作

打印操作打印堆栈。它返回顶部元素的数据。

  // Print the stack
  print() {
    let current = this.top;
    let result = "";
    while (current) {
      result  = current.data   " ";
      current = current.next;
    }
    console.log(result.trim());
  }

使用示例

// Usage example
const customStack = new CustomStack();
customStack.push(10);
customStack.push(20);
customStack.push(30);
console.log(customStack.pop()); // 30
console.log(customStack.peek()); // 20
console.log(customStack.getSize()); // 2
console.log(customStack.isEmpty()); // false
customStack.print(); // 20 10

在此实现中,我们使用链表(单链表)结构来表示我们的堆栈。每个元素都是一个节点,具有数据值和对下一个节点的引用。堆栈顶部始终是最近添加的节点。

结论

堆栈是计算机科学中的基本数据结构,遵循后进先出 (LIFO) 原则。它们用于各种应用程序,包括管理函数调用、实现撤消功能以及计算算术表达式。

在本教程中,我们介绍了堆栈的基础知识、使用它们的优缺点,以及它们在 JavaScript 中的实现(使用链表)。了解堆栈不仅仅是了解如何实现它们,还要认识到它们何时是解决问题的正确工具。

当您继续软件开发之旅时,您会发现堆栈是您解决问题的工具箱中不可或缺的工具。它们简单而强大,掌握它们将显着增强您设计高效算法和数据结构的能力。



保持更新和联系

确保您不会错过本系列的任何部分,并与我联系以更深入地讨论软件开发(Web、服务器、移动或抓取/自动化)、数据结构和算法以及其他令人兴奋的技术主题,关注我:

  • GitHub
  • 领英
  • X(推特)

敬请期待并快乐编码??‍??






          

            
  

            
                    
版本声明 本文转载于:https://dev.to/emmanuelayinde/understanding-stack-data-structure-a-step-by-step-guide-to-implementing-stack-in-javascript-3f62?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 为什么我的 Tomcat 服务器显示“所需的几个端口已在使用中”?
    为什么我的 Tomcat 服务器显示“所需的几个端口已在使用中”?
    Tomcat 服务器端口冲突:解决错误“Several Ports required are Already in Use”尝试在 Tomcat 上启动 JSP 程序时Eclipse 中,用户可能会遇到错误,指出 Tomcat 所需的多个端口已在使用中。出现此问题的原因是存在另一个 Tomcat 实...
    编程 发布于2024-11-17
  • 如何在 Java 中确定文件创建日期?
    如何在 Java 中确定文件创建日期?
    在 Java 中确定文件创建日期:揭示文件元数据确定文件的创建日期可能是一条有价值的信息,尤其是组织和管理文件时。 Java 提供了访问此元数据的机制,只要底层文件系统支持即可。Java 中的文件创建日期Java NIO(新输入/输出)提供用于检索文件元数据的选项,包括创建时间。通过利用 Basic...
    编程 发布于2024-11-17
  • 我们如何在 C/C++ 中实现锯齿状数组?
    我们如何在 C/C++ 中实现锯齿状数组?
    理解 C/C 中的交错数组 虽然交错数组的概念(其中行可以具有不同的长度)在标准 C/C 中,有一些技术可以实现类似的功能。尝试在 C/C 中声明交错数组,如下所示:int jagged[][] = { {0,1}, {1,2,3} };编译器会出错,突出显示为除第一个维度之外的所有维度指定边界的要...
    编程 发布于2024-11-17
  • 如何在 Sublime Text 2 中获取用户输入?
    如何在 Sublime Text 2 中获取用户输入?
    Sublime Text 2 中的用户输入用户尝试在 Sublime Text 2 中输入值时遇到困难,特别是在 Python 中使用 input() 或 gets 等函数时红宝石。控制台不提示输入,导致出现 EOFError 之类的错误。该问题是由于 Sublime Text 2 缺乏对控制台输入...
    编程 发布于2024-11-17
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-11-17
  • 除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-11-17
  • 如何执行存储在 MySQL 数据库中的 PHP 代码?
    如何执行存储在 MySQL 数据库中的 PHP 代码?
    执行存储在 MySQL 数据库中的 PHP执行存储在 MySQL 数据库中的 PHP 给 Web 开发带来了独特的挑战。要执行此操作,您可以使用 PHP 中内置的 eval() 函数。eval() 函数eval() 函数计算给定的字符串作为 PHP 代码。它执行解析后的代码,就像直接在脚本中编写一样...
    编程 发布于2024-11-17
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-11-17
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-11-17
  • 如何处理 PHP 8.1 中的返回类型冲突?
    如何处理 PHP 8.1 中的返回类型冲突?
    参考:返回类型冲突与 #[\ReturnTypeWillChange] 属性上下文:在 PHP 8.1 中,指定返回类型方法变得更加普遍,导致与现有的冲突实现。问题:当方法的返回类型从兼容类型更改为不兼容类型或未指定时,会出现以下弃用通知:Deprecated: Return type of [Me...
    编程 发布于2024-11-17
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-17
  • 为什么使用“enableReaderMode” API 将 NDEF 记录写入 NFC 标签?
    为什么使用“enableReaderMode” API 将 NDEF 记录写入 NFC 标签?
    如何将 NDEF 记录写入 NFC 标签将 NDEF 记录写入 NFC 标签需要使用 enableReaderMode API,该 API 提供卓越的性能和与基于意图的系统相比的可靠性。通过处理读写过程而不是依赖系统的默认行为,写入失败和卡损坏的风险显着降低。使用enableReaderMode A...
    编程 发布于2024-11-17
  • 以下是一些适合您文章内容的问题式标题:

* Mac OS X 上的 MySQLdb:为什么我收到“未加载库:libmysqlclient.16.dylib”?
* 如何修复“库未加载:l
    以下是一些适合您文章内容的问题式标题: * Mac OS X 上的 MySQLdb:为什么我收到“未加载库:libmysqlclient.16.dylib”? * 如何修复“库未加载:l
    Python:MySQLdb 和“未加载库:libmysqlclient.16.dylib”在尝试开发 Python/Django 应用程序时,您在 Mac OS X 10.6 上安装 MySQL-python 时遇到问题。尽管成功安装 MySQL,但导入 MySQLdb 失败,并显示错误消息“未加...
    编程 发布于2024-11-17
  • 发现渐进式 Web 应用程序为您的下一个项目带来的最大优势
    发现渐进式 Web 应用程序为您的下一个项目带来的最大优势
    Progressive online Apps, or PWAs, are quickly changing the online development landscape. PWAs are becoming the ideal way to connect mobile application...
    编程 发布于2024-11-17
  • 现代 C++ 实现中的 std::list::size() 真的是 O(1) 吗?
    现代 C++ 实现中的 std::list::size() 真的是 O(1) 吗?
    在现代实现中 std::list::size() 真的是 O(n) 吗?最近,一些开发人员建议std::list::size() 具有线性时间复杂度 (O(n))。但是,根据 C 标准,复杂性没有定义,并且可能会根据实现而变化。在 C 标准的早期版本 (C 03) 中,建议 size() 操作具有恒...
    编程 发布于2024-11-17

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3