数据结构-栈

554 阅读3分钟

栈是一种遵从后进先出(LIFO)原则的有序集合。新添加或待删除的元素都保持在栈的同一端, 称为栈顶,另一端就叫栈底。 在栈里, 新元素都靠近栈顶, 旧元素都接近栈底。

在现实生活中的例子就是下图里的一摞书或者餐厅里叠放的盘子。

image.png

栈也被用在编程语言的编译器和内存中保存变量、方法调用等, 也用于浏览器历史记录(浏览器的返回按钮)。

创建一个基于JavaScript对象是stack类

创建一个Stack类的最简单的方式是使用数组来存储其元素。在处理大量数据的时候(这在现实生活中的项目里很常见),我们同样需要评估如何操作数据是最高效的。在使用数组时,大部分方法的时间复杂度是O(n)。我们需要迭代整个数组直到找到要找的那个元素, 在最坏的情况下需要迭代数组的所有位置。 其中的n代表数组的长度。 如果数组有更多元素的话, 所需要的时间会更长。 另外,数组是一个有序集合, 为了保证元素排列有序, 它会占用更多的内存空间。 所以,我们可以使用一个JavaScript对象来存储所有的栈元素, 保证它们的顺序并且遵守LIFO原则。

首先声明一个Stack类

class Stack {
    constructor() {
        this.count = 0;
        this.items = {};
    }
}
  1. 向栈中插入元素
push(item) {
    this.items[this.count] = item;
    this.count++;
}
  1. 验证一个栈是否为空和它的大小

count属性也表示栈的大小。因此,我们可以简单的返回count的属性的值来实现size方法。

size() {
    return this.count;
}
  1. 验证栈是否为空,可以简单的判断count是否为0
isEmpty() {
    return this.count === 0;
}
  1. 从栈中弹出元素

pop() {
    if(this.isEmpty()) {
        return undefined;
    }
    
    this.count--;
    const result = this.items[this.count];
    delete this.items[this.count];
    return result;
}
  1. 查看栈顶的值
peek() {
    if(this.isEmpty()) {
        return undefined;
    }
    return this.items[this.count - 1];
}

6.清空栈

clear() {
    this.items = {};
    this.count = 0;
}

经典应用

使用栈结构去实现进制的转换。我们知道进制的转换是利用除基倒取余的方式去实现的。 即将数除以需要转换的进制数,得到商和余。只要商不为0。则继续除下去。取余数。最终将余数倒序排列完成转换。 这里就符合栈中的先进后出(FILO)。

  • 实现二进制的转换
function convert(num) {
    const stack = new Stack();
    let str = '';
    
    while(num / 2 !==0) {
        stack.push(num % 2);
        num = Math.floor(num / 2);
    }
    
    while (!stack.isEmpty()) {
        str = `${str}${stack.pop()}`
    }
    return str;
}
  • 任意进制的转换
/**
     * @param decNumber {number} 需要进行进制转换的数字
     * @param base {number} 进制转换的数字
     */
    function baseConverter(decNumber, base) {
      const stack = new Stack();
      const digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      let str = "";

      while (decNumber / base !== 0) {
        stack.push(decNumber % base);
        decNumber = Math.floor(decNumber / base);
      }

      while (!stack.isEmpty()) {
        str = `${str}${digits.charAt(Number(stack.pop()))}`;
      }
      return str;
    }

leetCode算法题

  1. 二叉树的前序遍历

对于没有二叉树数据结构认识的同学,数据结构-二叉树