数据结构-栈(Stack)

前言 今天讲解的是数据结构中的 "栈",

栈的数据结构

栈遵循的是一个先进后出的有序集合,新添加的元素和待删除的元素都保存在同一个端,我们通常叫栈顶,另一端叫栈底。新添加的元素都在栈顶
行李堆叠:在旅行中,我们可能会把行李逐渐堆叠起来。最后放入的行李在需要取出时通常会先取出,类似于栈的行为。

  • 我们将创建一个类来表示栈。简单地从创建一个 stack.js 文件并声明 Stack 类开始。
js 复制代码
class Stack {
  constructor() {
    this.items = [];
    this.count = 0
  }
}

创建一个stack类,创建一个数组, 数组可以进行任何操作;

  • 我们需要为栈添加以下方法

push(): 添加一个新元素到栈顶。 pop(): 移除栈顶的元素,同时返回被移除的元素。 peek(): 返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它)。 isEmpty(): 如果栈里没有任何元素就返回 true,否则返回 false。 clear(): 移除栈里的所有元素。 size(): 返回栈里的元素个数。该方法和数组的 length 属性很类似。 toString(): 打印栈内容

  • isEmpty(): 如果栈里没有任何元素就返回 true,否则返回 false。
js 复制代码
  isEmpty() {
    return this.count === 0;
  }
  • push() 添加一个新元素到栈顶。
js 复制代码
push(element) {
  this.items[this.count] = element; // 存放到栈顶
  this[count]++; // 栈大小+1
}
  • pop(): 移除栈顶的元素,同时返回被移除的元素。
js 复制代码
  pop() {
    if (this.isEmpty()) { // 删除前判断是否为空
      return undefined;
    }
    const result = this.item[this.count]; // 取栈顶元素
    delete this.item[this.count]; // 删除栈顶
    this.count--; // 栈大小-1
    return result; // 返回 栈顶元素
  }

其他方法也类似,主要是对数组的操作,在这里挑了几个来做例子

封装完成的栈

  • stack.js
js 复制代码
const _items = Symbol('_stackItems');
const _count = Symbol('_stackCount');
class Stack {
  constructor() {
    this[_items] = {};
    this[_count] = 0;
  }
  push(element) {
    this[_items][this[_count]] = element;
    this[_count]++;
  }
  pop() {
    if (this.isEmpty()) {
      return undefined;
    }
    const result = this[_items][this[_count]];
    delete this[_items][this[_count]];
    this[_count]--;
    return result;
  }
  peek() {
    return this[_items][this[_count]];
  }
  isEmpty() {
    return this[_count] === 0;
  }
  clear() {
    this[_items] = {};
    this[_count] = 0;
  }
  size() {
    return this[_count];
  }
  toString() {
    if (this.isEmpty()) {
      return '';
    }
    let objString = `${this[_items][0]}`;
    for (let i = 1; i < this[_count]; i++) {
      objString = `${objString},${this[_items][i]}`;
    }
    return objString;
  }
}
export default Stack;

这里用了Symbol来声明属性(不可变属性),用来保护栈内容不被破坏,(正常开发者做库之类的开源插件,大家会在变量前加一个下划线_,来表示私有变量;但是不保证某些开发者或者新人,去改动_私有变量,这种约定式并不安全) 用Symbol可以很好的避免这个问题(还是有方法能够破坏,并不代表属性永远不会受到破坏,只是一种防范的手段)

  • 测试:
js 复制代码
      const stack = new Stack();
      console.log(stack);
      stack.push(1);
      stack.push(2);
      stack.push(3);
      stack.push(4);
      // 2 删除栈一个元素
      stack.pop();
      // 3 查询结果
      console.log(stack.peek());
      console.log(stack.size());
      console.log(stack.isEmpty());
      console.log(stack.size());
      console.log(stack.isEmpty());
      console.log(stack.toString());
      console.log(stack.clear());
相关推荐
kyriewen12 分钟前
Claude自己跑出去hack了3家公司——我为什么还在用它写代码
前端·ai编程·claude
IT_陈寒19 分钟前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
子兮曰42 分钟前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端
程序员黑豆1 小时前
鸿蒙应用开发之@Styles 装饰器:定义可复用的组件样式
前端·harmonyos
程序员码歌1 小时前
我全程用 AI开发了一款微信小游戏,上线了
android·前端·游戏开发
咩咩啃树皮1 小时前
第52篇:前端工程化完整体系精讲——Vite构建、模块化、打包原理、规范体系、面试终极通关
前端·面试·职场和发展
妙码生花1 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(四十八):菜单规则管理实现
前端·后端·ai编程
FogLetter1 小时前
当JavaScript学会“分身术”:异步编程的进化简史
前端·javascript·面试
hunterandroid1 小时前
[鸿蒙从零到一] HarmonyOS 分布式能力与设备协同实战:从发现设备到任务闭环
前端
lichenyang4531 小时前
从图片创作到本地可复现的 AIGC 全栈闭环:AIGC Creative Studio 实践复盘
前端·后端