M4RKYU.SYSEdition 2027
Skip to content
LOCZH/安大略 · 加拿大/▸logs · frontend linear data structures deep dive arrays stacks queues and linked lists mp2待机OK/--:--:--EST
M4M4RK_YUportfolio
  • 创作
    创作Overview
    • 作品精选案例与项目记录
    • 游戏可玩原型与游戏开发日志
  • 影像
    影像Overview
    • 照片影像合集与视觉实验
    • 商店印刷品、海报和限量物件
  • 写作
    写作Overview
    • 博客长篇开发日志与现场笔记
    • 笔记短观察、链接与代码片段
  • 资源
    资源Overview
    • 工具38 款浏览器内开发工具
    • 链接每日使用的开发与设计书签
  • 关于
  • 联系
EN

同步 · dev.to / @markyu

Frontend Linear Data Structures Deep Dive: Arrays, Stacks, Queues, and Linked Lists

The Big Picture Before diving into stacks, queues, and linked lists, it helps to know...

发布日期
Jun 16
·
阅读时长
4 min read
·
点赞
4
computersciencealgorithmsbeginnersjavascript
在 dev.to 查看

本页目录

  • The Big Picture
  • Arrays
  • Adding Elements
  • Stack
  • Queue
  • Linked Lists
  • Why Not Just Use Arrays?
  • Structure
  • Basic Implementation
  • Insert
  • Delete
  • Two JS Gotchas Worth Knowing
  • Array Memory Isn't Always Contiguous
  • sort() Sorts Strings by Default
  • Quick Reference
  • Common Pitfalls

The Big Picture

Before diving into stacks, queues, and linked lists, it helps to know where they sit in the landscape.

Linear structures - arrays, linked lists, stacks, queues - arrange elements one after another. Each node has exactly one predecessor and one successor.

Non-linear structures - trees and graphs - are a different story for another day.

✦

Arrays

Arrays are the workhorse of JS. They use contiguous memory and give you direct access to any element by index - no traversal needed.

Adding Elements

push - appends to the end.

Simple enough, but there's a catch: arrays are initialized with a fixed capacity. When you exceed it, JS triggers a resize: allocate a bigger block, copy everything over, free the old space. It's not free.

Linked lists don't have this problem - they allocate memory per node, dynamically.

unshift - prepends to the beginning.

Every existing element has to shift right by one to make room. The longer the array, the worse the performance. Fine for small arrays; avoid it in hot paths.

splice - the Swiss Army knife.

array.splice(startIndex, deleteCount, ...itemsToAdd)
  • startIndex: where to begin
  • deleteCount: how many to remove (pass 0 to insert without deleting)
  • ...itemsToAdd: optional elements to insert

Key things to know: splice mutates the original array and returns the deleted elements as a new array (empty array if nothing was deleted). Like all native array methods - push, pop, unshift, shift - it's not a pure function.

const arr = [1, 2];

arr.splice(1, 0, 3);   // insert 3 at index 1
console.log(arr);      // [1, 3, 2]

arr.splice(1, 1);      // delete element at index 1
console.log(arr);      // [1, 2]
✦

Stack

A stack is LIFO - Last In, First Out. Think of it like a stack of plates: you can only add or remove from the top.

push → [bottom ... top] ← pop

In JS, implement with a plain array:

const stack = [];

stack.push('A');
stack.push('B');
stack.push('C');

while (stack.length) {
  console.log(stack.pop()); // C, B, A
}
  • push to add to the top
  • pop to remove from the top
  • Peek without removing: stack[stack.length - 1]
✦

Queue

A queue is FIFO - First In, First Out. Like a checkout line: first in, first served.

push → [back ... front] → shift
const queue = [];

queue.push('Alice');
queue.push('Bob');
queue.push('Charlie');

while (queue.length) {
  console.log(queue.shift()); // Alice, Bob, Charlie
}

Heads up: shift has an O(n) cost - every element shifts left by one index after removal. For small arrays, no big deal. At scale, this becomes a bottleneck. If you're building a high-throughput queue, a linked list implementation is the right call.

✦

Linked Lists

Why Not Just Use Arrays?

Arrays are great when you need fast random access. But inserting or deleting anywhere except the tail requires shifting elements - O(n) work.

Linked lists flip the tradeoff:

ArrayLinked List
MemoryContiguous (if uniform types)Scattered, node-by-node
Random accessO(1)O(n) - must traverse
Insert/deleteO(n) at non-tail positionsO(1) once you have the node
Best forFrequent reads, small dataFrequent writes, large data

Structure

Each node holds two things:

  • val: the data
  • next: a pointer to the next node (null if it's the tail)

In JS, a linked list is just nested objects:

{
  val: 1,
  next: {
    val: 2,
    next: null
  }
}

To access any element, you start at head and follow next pointers until you reach your target. There's no shortcut - no index to jump to directly.

Basic Implementation

function ListNode(val) {
  this.val = val;
  this.next = null;
}

const head = new ListNode(1);
head.next = new ListNode(2);
// 1 -> 2 -> null

Insert

Find the predecessor node, point its next to the new node, then point the new node's next to the original successor. No data movement, just pointer reassignment - O(1).

Delete

Find the predecessor, skip the target by pointing next directly to the target's successor. Done - O(1).

The expensive part with linked lists isn't insert/delete - it's finding the right node, which always costs O(n).

✦

Two JS Gotchas Worth Knowing

Array Memory Isn't Always Contiguous

JS engines optimize for uniform-type arrays. Mix types and the engine may fall back to a hash map structure internally, losing the contiguous memory layout.

const fast = [1, 2, 3, 4];           // likely contiguous
const slower = ['a', 1, { b: 2 }];   // likely hash map internally

Don't mix types in performance-sensitive arrays.

sort() Sorts Strings by Default

[10, 2, 5].sort()                    // [10, 2, 5] - ASCII order, wrong
[10, 2, 5].sort((a, b) => a - b)     // [2, 5, 10] - correct

Always pass a comparator when sorting numbers.

✦

Quick Reference

StructureAddRemoveAccessRule
Arraypush O(1)*pop O(1)O(1) by index-
StackpushpopO(n)LIFO
Queuepushshift O(n)O(n)FIFO
Linked ListO(1) once positionedO(1) once positionedO(n) traversal-

*Amortized - occasional resize at O(n)

✦

Common Pitfalls

  • unshift is slow at scale - it shifts every element. Use sparingly.
  • Array-based queues degrade - shift is O(n). For high volume, use a linked list.
  • All native array methods mutate - push, pop, shift, unshift, splice all modify in place. None are pure functions.
  • Don't mix array element types - you lose the contiguous memory advantage.
  • Stacks and queues aren't separate data structures - they're arrays (or linked lists) with constrained access rules.
  • Linked list insert/delete is fast; finding the node isn't - the O(n) cost is in traversal, not the operation itself.

相关阅读

algorithms

JS Sorting Algorithms Every Developer Should Know

You call .sort() every day without thinking about it. But the sorting algorithm your language's...

algorithms

A* Search Finally Clicked When I Drew the Grid

A practical developer-friendly explanation of heuristic search, Greedy Best-First Search, and A* using a grid example instead of textbook language.

networking

Network Address Calculation: The Subnet Math That Matters

A practical subnetting guide showing how to calculate a network address from an IP address and mask using binary math and simple examples.

原文发布

本文首发于 dev.to,评论与点赞保留在原站。

在 dev.to 继续阅读
上一篇JS Sorting Algorithms Every Developer Should KnowYou call .sort() every day without thinking about it. But the sorting algorithm your language's...
返回全部文章
返回档案
频道开放·随时打个招呼 · 2026
--:--:--EST
联系

看到什么有意思的?和我聊聊。

这是一个作品集,不是服务 · 但每一条留言我都会看 — 如果哪里让你有所触动,或者只想打个招呼,欢迎写信过来。

开启对话

订阅

偶尔收到一封简讯

来自 m4rkyu.com 的笔记与日志——简短、标注日期、没有杂音。随时可退订。

作品

线上发布、游戏作品与视觉档案。

  • 项目
  • 游戏
  • 档案
  • 日志

资源

每日好用的工具与个人收藏的链接库。

  • 搜索
  • 最新
  • 工具
  • 链接
  • 笔记
  • 主题
  • RSS
  • JSON Feed
  • 商店

工作室

背景、联系方式以及合作渠道。

  • 关于
  • 联系
  • 更新日志
  • 技术说明
  • 简历筹备中

社交

在常去的平台上找到我。

  • GitHub
  • dev.to
  • 邮件

领英 · Instagram · YouTube · 敬请期待

M4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYU
始于 2024
ZhenXiao Mark YuZhenXiao Mark Yu
© 2026 ZhenXiao Mark Yu·加拿大 安大略·隐私条款
  • 邮件
  • GitHub
  • dev.to
由 Next.js 16 · React 19 · Tailwind 4 构建

由 Next.js 16 · React 19 · Tailwind 4 构建