TypeScript实现栈数据结构

64 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 12 月更文挑战」的第 2 天,点击查看活动详情

最近在学习 Javascript 数据结构与算法相关知识,数据结构与算法对程序员来说就像是内功心法,只有不断修炼自己的内功,才能从容不迫的应对市场上各种让人应接不暇的框架,达到以不变应万变。学习数据结构与算法的过程中不仅要能看懂更要多写多练,今天就来手写下栈数据结构。

栈数据结构

栈是一种遵从后进先出原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。

基于数组实现的栈

class StackArray<T> {
  private items: T[]; // 定义私有属性

  constructor() {
    this.items = [];
  }
  // 入栈
  push(element: T) {
    this.items.push(element);
  }
  // 出栈
  pop() {
    return this.items.pop();
  }
  // 查看栈顶元素
  peek() {
    return this.items[this.size() - 1];
  }
  // 检查栈是否为空
  isEmpty() {
    return this.size() === 0;
  }
  // 清空栈
  clear() {
    this.items = [];
  }
  // 栈大小
  size() {
    return this.items.length;
  }
  toString() {
    return this.items.toString();
  }
}

利用数组的 push,pop 实现一个栈结构还是很容易的

基于对象实现的栈

这里为什么使用对象来保存栈中元素?

因为在使用数组时,大部分方法的时间复杂度是 O(n)。并且数组是元素的一个有序集合,为了保证元素排列有序,它会占用更多的内存空间。

class Stack<T> {
  private count: number;
  private items: Record<number, T>;

  constructor() {
    this.count = 0; // 用于记录栈大小
    this.items = {};
  }
  push(element: T) {
    this.items[this.count] = element;
    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];
  }
  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;
  }
}

使用场景

所有后进先出的场景 函数调用堆栈
leetcode 练习题:20 有效的括号

题目描述:

给定一个只包括 '(',')','{','}','[',']'  的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function (s) {
  const arr = [];
  for (let i = 0; i < s.length; i++) {
    if (["(", "[", "{"].includes(s[i])) { 
      arr.push(s[i]); // 左括号入栈
    } else if (
      (s[i] === ")" && arr[arr.length - 1] === "(") ||
      (s[i] === "]" && arr[arr.length - 1] === "[") ||
      (s[i] === "}" && arr[arr.length - 1] === "{")
    ) {
      arr.pop(); // 能闭合就出栈
    } else {
      return false;
    }
  }
  return arr.length === 0;
};

解题思路是利用栈后进先出的特点,左括号入栈,如果右括号与栈顶左括号闭合就出栈,如果都能闭合那栈最后一定为空。

栈数据结构还是比较简单 通俗易懂的,下一篇介绍用typescript实现队列数据结构