返回

TypeScript 数据结构与算法:栈

前端

概述

栈是一种遵循后进先出(LIFO)原则的数据结构。这意味着最后添加的元素是第一个被删除的元素。栈通常使用数组或链表实现。

实现

在 TypeScript 中,栈可以通过数组或链表来实现。数组实现更为简单,但链表实现可以提供更好的性能,特别是当栈很大时。

数组实现

class Stack {
  private items: any[];

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

  // 压入元素
  push(item: any) {
    this.items.push(item);
  }

  // 弹出元素
  pop(): any {
    return this.items.pop();
  }

  // 查看栈顶元素
  peek(): any {
    return this.items[this.items.length - 1];
  }

  // 检查栈是否为空
  isEmpty(): boolean {
    return this.items.length === 0;
  }

  // 获取栈的大小
  size(): number {
    return this.items.length;
  }
}

链表实现

class StackNode {
  value: any;
  next: StackNode | null;

  constructor(value: any) {
    this.value = value;
    this.next = null;
  }
}

class Stack {
  private top: StackNode | null;
  private size: number;

  constructor() {
    this.top = null;
    this.size = 0;
  }

  // 压入元素
  push(item: any) {
    const node = new StackNode(item);
    node.next = this.top;
    this.top = node;
    this.size++;
  }

  // 弹出元素
  pop(): any {
    if (this.isEmpty()) {
      return null;
    }
    const value = this.top!.value;
    this.top = this.top!.next;
    this.size--;
    return value;
  }

  // 查看栈顶元素
  peek(): any {
    if (this.isEmpty()) {
      return null;
    }
    return this.top!.value;
  }

  // 检查栈是否为空
  isEmpty(): boolean {
    return this.size === 0;
  }

  // 获取栈的大小
  size(): number {
    return this.size;
  }
}

操作

栈支持以下操作:

  • 压入(push) :将元素添加到栈顶。
  • 弹出(pop) :从栈顶删除元素。
  • 查看栈顶元素(peek) :查看栈顶元素,但不将其删除。
  • 检查栈是否为空(isEmpty) :检查栈是否为空。
  • 获取栈的大小(size) :获取栈的大小。

时间和空间复杂度

栈的时间和空间复杂度如下:

操作 时间复杂度 空间复杂度
压入(push) O(1) O(1)
弹出(pop) O(1) O(1)
查看栈顶元素(peek) O(1) O(1)
检查栈是否为空(isEmpty) O(1) O(1)
获取栈的大小(size) O(1) O(1)

应用

栈在计算机科学中有很多应用,包括:

  • 撤销/重做操作
  • 函数调用
  • 表达式求值
  • 递归
  • 图形处理
  • 编译器

实际应用示例

我们来看一个实际应用示例。假设我们有一个字符串,我们需要反转它。我们可以使用栈来轻松实现这个任务。

function reverseString(str: string): string {
  const stack = new Stack();

  // 将字符串中的每个字符压入栈中
  for (let i = 0; i < str.length; i++) {
    stack.push(str[i]);
  }

  // 从栈中弹出字符并将其添加到一个新的字符串中
  let reversedString = "";
  while (!stack.isEmpty()) {
    reversedString += stack.pop();
  }

  return reversedString;
}

这个函数的复杂度为 O(n),其中 n 是字符串的长度。

总结

栈是一种非常有用的数据结构,在计算机科学中有很多应用。栈的实现非常简单,并且具有良好的时间和空间复杂度。