当前位置: 首页 > news >正文

总结前端常用数据结构 之 栈篇【JavaScript 】

真正的大师永远都怀着一颗学徒的心。——易大师

栈!

  • 什么是栈?
  • 栈的增加/删除:
  • 栈常用的辅助方法:
  • 封装栈:
  • 封装栈的实际应用例子:
    • 十进制转二进制(辗转相除法):
    • 十进制转任意进制:
  • 栈和数组的区别:
  • 栈和数组对比的应用场景:
  • 栈-前端应用场景举例:
    • ‌页面路由历史管理:
    • ‌撤销操作:
    • 递归函数调用栈:

什么是栈?

栈是一种特殊的线性数据结构,它只允许在一端进行插入和删除操作,这一端被称为栈顶,相对的另一端称为栈底。‌ 栈按照后进先出 Last in First Out(LIFO)的原则存储数据,即最后进入栈的数据会最先被删除。【限定仅在表尾进行插入和删除操作的线性表

栈的增加/删除:

  • Stack增加使用 push() 方法
  • Stack删除使用 pop() 方法

可以理解为栈是一个特殊的数组。

栈常用的辅助方法:

‌方法/属性‌作用示例
length获取当前栈元素数量if (stack.length === 0) {…}
‌peek()查看栈顶元素(需自定义实现)function peek() { return stack.at(-1) }
‌isEmpty()判断栈是否为空(需自定义实现)function isEmpty() { return stack.length === 0 }

封装栈:

    // push添加一个元素到栈顶
    // pop出栈
    // peek 返回栈顶
    // isEmpty() 判断栈是否为空
    // clear() 清空栈结构
    // size() 栈的元素个数
    // toString() 转换成普通的字符串

    class Stack{
       // 这里的#是私有的 es13中提到
        #items = [];
        pop(){
          return this.#items.pop();
        }
        push(data){
          this.#items.push(data);
        }
        peek(){
          // return this.#items[this.items.length - 1];
          return this.#items.at(-1);
        }
        isEmpty(){
          return this.#items.length === 0;
        }
        clear(){
          this.#items = [];
        }
        size(){
          return this.#items.length;
        }
        toString(){
          return this.#items.join("");
        }
    }
    let stack = new Stack();

封装栈的实际应用例子:

十进制转二进制(辗转相除法):

接上面栈的代码:

 function convert (decNumber) {
      let remStack = new Stack();
      let string = "";
      let number = decNumber;

      while (number > 0) {
        remStack.push(number % 2);
        number = Math.floor(number / 2);
      }
      while (!(remStack.isEmpty())) {
        string += remStack.pop();
      }
      return string;
    }
    console.log('50转为二进制是:', convert(50));

十进制转任意进制:

function convert (decNumber, base) {
      let remStack = new Stack();
      let string = "";
      let number = decNumber;
      let baseString = "0123456789ABCDEF"

      while (number > 0) {
        remStack.push(number % base);
        number = Math.floor(number / base);
      }
      while (!(remStack.isEmpty())) {
        string += baseString[remStack.pop()];
      }
      return string;
    }
    convert(50, 2);
    convert(50, 8);
    convert(50, 16);

栈和数组的区别:

特性数组
操作方式自由增删改查(通过索引)仅允许push(入栈)、pop(出栈)
‌访问权限任意位置直接访问仅能访问栈顶元素
‌底层实现内存中的连续空间可用数组或链表实现
‌灵活性高(可动态扩容或缩容)低(严格遵循LIFO规则)

栈和数组对比的应用场景:

  • 数组‌ :适合需要快速随机访问的场景,如排序算法、矩阵运算、数据缓存等。
  • 栈‌:适合需要回溯或反转顺序的场景,如函数调用栈、括号匹配、表达式求值、浏览器前进后退等。

栈-前端应用场景举例:

‌页面路由历史管理:

// 模拟浏览器后退栈
const historyStack = new Stack();
historyStack.push("/home");
historyStack.push("/detail");
historyStack.pop(); // 返回上一页

‌撤销操作:

const undoStack = new Stack();
const redoStack = new Stack();

function doAction(action) {
  undoStack.push(action);
  redoStack.items = []; // 清空重做栈
}

递归函数调用栈:

代码举例计算阶乘:n × (n-1) × … × 1

function factorial(n, stack = new Stack()) {
  stack.push(`计算 factorial(${n})`);
  if (n === 1) return 1;
  const result = n * factorial(n - 1, stack);
  stack.pop(); // 调用完成出栈
  return result;
}

相关文章:

  • ipe网络安全
  • 30.C++多态 3 (多态的原理,虚指针,虚函数表,抽象类)
  • Python学习第十七天之PyTorch保姆级安装
  • 数据结构与算法-图论-最短路-拓展运用
  • CSDN年度评选揭晓,永洪科技AI技术与智能应用双星闪耀
  • 双重机器学习DML
  • HTTPS 与 HTTP 的区别在哪?
  • 【FL0091】基于SSM和微信小程序的社区二手物品交易小程序
  • 002 Java操作kafka客户端
  • Spring Security实战:如何实现OAuth2.0认证与授权?
  • Spring Boot 实战:构建 RESTful API 服务
  • Vue 项目中配置代理的必要性与实现指南
  • ChatGPT入驻Safari,AI搜索时代加速到来
  • 打包rocketmq-dashboard报错问题记录
  • 游戏引擎学习第125天
  • 免费使用SCI润色神器QuillBot
  • LabVIEW同步数据采集功能
  • 力扣1:两数之和
  • mac设置 pip 的镜像
  • Windows逆向工程入门之LOOP与REP指令的深度解析
  • 上海北外滩,未来五年将如何“长个子”“壮筋骨”?
  • 75万买299元路由器后续:重庆市纪委、财政局、教委联合调查
  • 王毅谈中拉论坛十年成果
  • 反制美国钢铝关税!印度拟对美国部分商品征收关税
  • 最高降价三成,苹果中国iPhone开启大促销,能拉动多少销量?
  • 媒体和打拐志愿者暗访长沙一地下代孕实验室,警方已控制涉案人员