Algorithms and Data Structures in JavaScript (Node.js): From Basics to Advanced Techniques
Understanding algorithms and data structures is a fundamental skill for any developer working with JavaScript, especially in the Node.js environment. Without this knowledge, it is impossible to create efficient, scalable, and fast applications. In this article, we will break down the key concepts that will help you write optimized code and successfully pass technical interviews.
Why are algorithms and data structures important for Node.js?
Node.js, built on the V8 engine, allows you to run JavaScript on the server. Here, unlike in the browser, performance is critical: the server processes thousands of requests simultaneously. Choosing the wrong data structure can slow down operations by hundreds of times. For example, searching for an element in an array of 10,000 records might take 0.1 ms, while in a linked list it could take 10 ms. The difference is obvious.
The main data structures you will use:
- Array — a basic but powerful tool. Fast access by index (O(1)), but slow insertion/deletion at the beginning (O(n)).
- Hash Table (Object, Map) — ideal for storing key-value pairs. Average operation complexity is O(1).
- LinkedList — efficient for frequent insertions and deletions in the middle of the list.
- Stack and Queue — indispensable for processing data streams (e.g., tasks in the event loop).
- Tree (Binary Tree, BST) — for hierarchical data and fast searching.
- Graph — for modeling relationships (social networks, routes).
Basic sorting and searching algorithms in JavaScript
Let's look at two classic tasks: sorting an array and binary search. In Node.js, these algorithms are implemented directly, without third-party libraries.
Quick Sort
This is one of the most efficient algorithms with an average complexity of O(n log n). It works on the "divide and conquer" principle.
function quickSort(arr) { if (arr.length <= 1) return arr;
const pivot = arr[arr.length - 1]; const left = []; const right = [];
for (let i = 0; i < arr.length - 1; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } }
return [...quickSort(left), pivot, ...quickSort(right)];}
// Example usageconst numbers = [34, 7, 23, 32, 5, 62];console.log(quickSort(numbers)); // [5, 7, 23, 32, 34, 62]Binary Search
An algorithm for sorted arrays. Complexity is O(log n) — an order of magnitude faster than linear search.
function binarySearch(arr, target) { let left = 0; let right = arr.length - 1;
while (left <= right) { const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid; if (arr[mid] < target) left = mid + 1; else right = mid - 1; }
return -1; // element not found}
const sortedArray = [1, 3, 5, 7, 9, 11, 13];console.log(binarySearch(sortedArray, 7)); // 3Hash Tables: when performance matters
In Node.js, hash tables are implemented via the built-in Map and Object objects. They provide data access in O(1) on average. However, it is important to understand how to avoid collisions and performance loss.
Example: counting word frequency using Map
function countWords(text) { const wordMap = new Map(); const words = text.toLowerCase().split(/\\W+/);
for (const word of words) { if (word) { wordMap.set(word, (wordMap.get(word) || 0) + 1); } }
return wordMap;}
const text = "JavaScript и Node.js. JavaScript — это язык программиров";