JavaScript 数据结构与算法 之 栈

简介: JavaScript 数据结构与算法 之 栈

栈结构

栈是一种遵从后进先出( LIFO)原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。
  1. 创建基于数组的栈
class Stack {
  constructor() {
    this.items = [];
  }
  // 元素进栈
  push(item) {
    this.items.push(item);
  }
  // 元素出栈
  pop() {
    return this.items.pop();
  }
  // 查看栈顶元素
  peek() {
    return this.items[this.items.length - 1];
  }
  // 检查栈是否为空
  isEmpty() {
    return this.items.length === 0;
  }
  // 返回栈的长度
  size() {
    return this.items.length;
  }
  // 清空栈元素
  clear() {
    this.items = [];
  }
}

const stack = new Stack();
console.log(stack.isEmpty()); // 输出true
stack.push(5);
stack.push(8);
console.log(stack.peek()); // 输出8
stack.push(11);
console.log(stack.size()); // 输出 3
console.log(stack.isEmpty()); // 输出 false
stack.push(15);
stack.pop();
stack.pop();
console.log(stack.size()); // 输出 2

JS对象实现Stack类

class Stack {
  constructor() {
    this.count = 0;
    this.items = {};
  }
  push(item) {
    this.items[this.count] = item;
    this.count++;
  }
  pop() {
    if (this.isEmpty()) {
      return undefined;
    }
    this.count--;
    const result = this.items[this.count];
    delete this.items[this.count];
    return result;
  }
  peek() {
    if (this.isEmpty()) {
      return undefined;
    }
    return this.items[this.count - 1];
  }
  clear() {
    this.items = {};
    this.count = 0;
  }
  size() {
    return this.count;
  }
  isEmpty() {
    return this.count === 0;
  }
  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;
  }
}

保护数据结构内部元素

  • 使用下划线命名约定
class Stack {
  constructor() {
    this._count = 0;
    this._items = {};
  }
}
  • 使用限定作用域Symbol实现类
Object.getOwnPropertySymbols 方法能够取到类里面声明的所有 Symbols 属性,这种方法还是不安全
const _items = Symbol('stackItems');
class Stack {
  constructor() {
    this[_items] = {};
  }
}
  • WeakMap实现
const _items = new WeakMap();
class Stack {
  constructor() {
    items.set(this, []);
  }
  push(item) {
    const s = items.get(this);
    s.push(item);
  }
  pop() {
    const s = items.get(this);
    const r = s.pop();
    return r;
  }
  // ...
}

栈应用

  • 进制转换

    • 十进制转二进制
    function decimalToBinary(decNumber) {
      const remStack = new Stack();
      let number = decNumber;
      let rem;
      let binaryString = '';
      while (number > 0) {
        rem = Math.floor(number % 2);
        remStack.push(rem);
        number = Math.floor(number / 2);
      }
      while (!remStack.isEmpty()) {
        binaryString += remStack.pop().toString();
      }
      return binaryString;
    }
    • 任意进制转换(2~36)
    function baseConverter(decNumber, base) {
      const remStack = new Stack();
      const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
      let number = decNumber;
      let rem;
      let baseString = '';
    
      if (!(base >= 2 && base <= 36)) {
        return '';
      }
      while (number > 0) {
        rem = Math.floor(number % base);
        remStack.push(rem);
        number = Math.floor(number / base);
      }
      while (!remStack.isEmpty()) {
        baseString += digits[remStack.pop()];
      }
      return baseString;
    }
相关文章
|
25天前
|
JavaScript 算法 前端开发
采招网JS逆向:基于AES解密网络数据
采招网JS逆向:基于AES解密网络数据
37 0
|
22天前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
22天前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
9天前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
|
11天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
12天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
14 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
16天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
28天前
|
JSON JavaScript 数据格式
js实现更新数据
js实现更新数据
36 1
|
1月前
|
负载均衡 网络协议 安全
DKDP用户态协议栈-kni
DKDP用户态协议栈-kni
|
1月前
|
存储 安全 编译器
缓冲区溢出之栈溢出(Stack Overflow
【8月更文挑战第18天】
55 3