引言:为什么要学习 JavaScript 中的算法与数据结构?
任何程序都不只是一组指令,而是一种有效管理数据的方式。对于 JavaScript(尤其是在 Node.js 环境中)的初学者开发者来说,理解 算法与数据结构 不仅仅是一项学术任务,更是一项直接影响代码性能和可读性的实用技能。
JavaScript 是一种动态类型语言,但这并不意味着不需要了解 数组、栈 或 队列 的工作原理。没有这些知识,你的代码可能会变得缓慢,逻辑也会变得混乱。在本文中,我们将通过 Node.js 示例来解析基本的数据结构和算法,帮助你编写更高效的应用程序。
JavaScript (Node.js) 中的基本数据结构
JavaScript 内置了几种数据结构,但要深入理解,你需要能够手动实现它们。这能让你更好地控制内存和执行速度。
数组 (Array)
JS 中的数组是动态列表。它们非常适合存储有序数据。但需要注意的是,在数组开头插入或删除元素(unshift/shift)是 O(n) 操作,因为需要移动所有元素。
// 创建数组const fruits = ['apple', 'banana', 'cherry'];
// 在末尾添加 (O(1))fruits.push('orange');
// 从末尾删除 (O(1))fruits.pop();
// 查找元素 (O(n))const index = fruits.indexOf('banana');console.log(index); // 1栈 (Stack)
栈遵循后进先出(LIFO)原则。它是处理函数调用、撤销操作(undo)或检查代码中括号匹配不可或缺的结构。
class Stack { constructor() { this.items = []; }
push(element) { this.items.push(element); }
pop() { if (this.isEmpty()) return null; return this.items.pop(); }
peek() { return this.items[this.items.length - 1]; }
isEmpty() { return this.items.length === 0; }}
// 使用示例:检查括号匹配const stack = new Stack();const str = '({[]})';let isValid = true;
for (let char of str) { if (char === '(' || char === '{' || char === '[') { stack.push(char); } else { const last = stack.pop(); if ( (char === ')' && last !== '(') || (char === '}' && last !== '{') || (char === ']' && last !== '[') ) { isValid = false; break; } }}
console.log(isValid && stack.isEmpty()); // true队列 (Queue)
队列遵循先进先出(FIFO)原则。它用于管理任务、处理 Node.js 中 Web 服务器的请求或实现缓冲区。
class Queue { constructor() { this.items = {}; this.front = 0; this.rear = 0; }
enqueue(element) { this.items[this.rear] = element; this.rear++; }
dequeue() { if (this.isEmpty()) return null; const item = this.items[this.front]; delete this.items[this.front]; this.front++; return item; }
isEmpty() { return this.front === this.rear; }
size() { return this.rear - this.front; }}
// 示例:任务处理const taskQueue = new Queue();taskQueue.enqueue('任务 1');taskQueue.enqueue('任务 2');console.log(taskQueue.dequeue()); // 任务 1JavaScript 中的搜索算法
数据搜索是最常见的操作之一。我们来分析两种基本算法:线性搜索和二分搜索。
线性搜索 (Linear Search)
遍历