数据结构与算法(JS版)—— 栈

1. 概念

  • 类似于数组,但在添加和删除元素时更为可控
  • 是遵从后进先出原则(LIFO)的有序集合
  • 新元素或待删除的元素都靠近栈顶
  • 旧元素都接近栈底
  • 现实生活中,类似于一摞书或者一叠盘子
  • 应用:编译器内存中保存变量、方法调用等;浏览器历史记录

2. 创建一个基于数组的栈

  • 需要实现的方法:

    • push(element(s)):添加一个或几个新元素到栈顶
    • pop():移除栈顶的元素,同时返回被移除的元素
    • peek():返回栈顶元素,不改变栈
    • isEmpty():是否为空栈,返回布尔值
    • clear():清空栈
    • size():返回栈的元素个数
    • toString():将栈元素变成字符串输出
  • 代码实现 stack-array.js

class Stack {
    constructor() {
        this.items = [];
    }

    push(i) {
        this.items.push(i);
    }

    pop() {
        // 注意要有返回值
        return this.items.pop();
    }

    peek() {
        // 返回栈顶元素
        return this.items[this.items.length - 1];
    }

    isEmpty() {
        return this.items.length === 0;
    }

    clear() {
        this.items = [];
    }

    size() {
        return this.items.length;
    }

    toString() {
        return this.items.toString();
    }
}

// 使用
const stack = new Stack();
console.log(stack.isEmpty());

stack.push(5);
stack.push(8);
stack.push(1);
console.log(stack.pop());
console.log(stack.peek());
console.log(stack.size())
console.log(stack.toString());

补充

  • 在使用数组时,大部分方法的时间复杂度是O(n)。
    • O(n)的意思是,我们需要迭代整个数组直到找到要找的那个元素,最坏的情况下需要迭代数组的所有位置,其中n代表数组的长度。
  • 数组是元素的一个有序集合,为了保证元素排列有序,它会占用更多的内存空间。

3. 创建一个基于对象的栈

  • 为了占用较少内存,且降低时间复杂度,可以基于对象创建Stack类
  • 类中需要一个count属性辅助记录
  • 除了toString方法,时间复杂度均为O(1)
class Stack {
    constructor() {
        this.items = {};
        this.count = 0;
    }

    push(i) {
        this.items[this.count] = i;
        this.count++;
    }

    pop() {
        // 不要忘记为空判断
        if (this.isEmpty()) {
            return undefined;
        }

        this.count--;
        // 需要先用变量保存一下this.items[this.count]值,否则返回undefined
        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];
    }

    isEmpty() {
        return this.count === 0;
    }

    clear() {
        this.items = {};
        // 计数不要忘记归0
        this.count = 0;
    }

    size() {
        return this.count;
    }

    toString() {
        if (this.isEmpty()) {
            return '';
        }
        return Object.values(this.items).toString();
    }
}

4. 保护数据结构内部元素(to do)

5. 用栈解决问题(to do)

十进制转二进制

有效括号

汉诺塔

函数调用堆栈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录介绍 01.栈由简单数据实现1.1 简单数组代码实现1.2 可能出现问题1.3 性能和局限性 02.栈由动态数...
    杨充211阅读 1,579评论 0 2
  • 栈是限定仅在表尾进行插入和删除操作的线性表。表尾端称为栈顶,表头端称为栈底。不含元素的空表称为空栈。栈是后进先出的...
    yinxmm阅读 1,849评论 0 0
  • 前言:题图无关,只是好看,接下来就来复习一下栈和队列的相关知识 前序文章: 数据结构与算法(1)——数组与链表(h...
    我没有三颗心脏阅读 3,365评论 3 8
  • 4.2.1 栈的定义 栈是限定仅在表尾进行插入和删除操作的线性表 我们把允许插入和删除的一端称为栈顶,另一端称为栈...
    镜花水月阅读 272评论 0 0
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 126,276评论 2 7