JavaScript中的数据结构实现:栈与队列

栈和队列可通过JavaScript数组或自定义类实现。1. 栈遵循后进先出(LIFO),用push/pop操作实现高效入栈出栈;2. 队列遵循先进先出(FIFO),可用push/shift操作,但shift为O(n)影响性能;3. 可通过类封装实现peek、front、isEmpty等方法;4. 栈适用于递归模拟、表达式求值,队列适合任务调度、BFS等场景;5. 高性能需求时建议用对象+指针或链表优化队列实现。

JavaScript 中虽然没有内置的栈和队列类型,但我们可以利用数组或自定义类来实现这两种常用的数据结构。它们在算法设计、函数调用管理、任务调度等场景中非常有用。下面分别介绍栈和队列的基本原理与实现方式。

栈的实现(后进先出)

栈是一种遵循“后进先出”(LIFO, Last In First Out)原则的数据结构。常见的操作包括入栈(push)、出栈(pop)、查看栈顶元素(peek)和判断是否为空。

使用 JavaScript 数组可以轻松模拟栈行为:

  • push():将元素添加到栈顶
  • pop():移除并返回栈顶元素
  • peek():返回栈顶元素但不移除
  • isEmpty():判断栈是否为空

以下是基于类的栈实现:

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

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

pop() { if (this.isEmpty()) return undefined; return this.items.pop(); }

peek() { if (this.isEmpty()) return undefined; return this.items[this.items.length - 1]; }

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

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

示例使用:

const stack = new Stack();
stack.push(1);
stack.push(2);
console.log(stack.peek()); // 2
console.log(stack.pop());  // 2
console.log(stack.size()); // 1

队列的实现(先进先出)

队列遵循“先进先出”(FIFO, First In First Out)原则。常用于任务排队、广度优先搜索等场景。基本操作包括入队(enqueue)、出队(dequeue)、查看队首元素(front)和判断是否为空。

虽然可以用数组的 push 和 shift 实现,但 shift 操作的时间复杂度为 O(n),效率较低。下面是一个简单但实用的队列类:

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

enqueue(element) { this.items.push(element); }

dequeue() { if (this.isEmpty()) return undefined; return this.items.shift(); // 注意:shift 是 O(n) }

front() { if (this.isEmpty()) return undefined; return this.items[0]; }

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

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

示例使用:

const queue = new Queue();
queue.enqueue('a');
queue.enqueue('b');
console.log(queue.front());   // 'a'
console.log(queue.dequeue()); // 'a'
console.log(queue.size());    // 1

若需更高性能,可考虑使用双指针或链表实现,避免频繁的元素移动。

优化建议与使用场景

在实际开发中,选择合适的数据结构能显著提升代码效率和可读性。

  • 栈适用于递归模拟、括号匹配、表达式求值等问题
  • 队列适合处理任务调度、消息传递、BFS 等需要顺序处理的场景
  • 若对性能要求高,可改用对象 + 指针模拟队列,实现 O(1) 出队
  • 注意数组方法的性能差异:pop 和 push 是 O(1),shift 和 unshift 是 O(n)

基本上就这些。掌握栈和队列的手动实现,有助于深入理解 JavaScript 的数据操作机制,也能在不依赖外部库的情况下快速构建逻辑清晰的程序结构。