🧠 引言
作为一名经验丰富的前端工程师,你可能精通各种框架、响应式设计、组件封装……但只要面试官一句话:“你能手写一个链表吗?”你可能就栽了。
链表 作为算法入门最基础、但最容易被忽视的数据结构,常常让习惯了数组思维的前端人一脸懵。
今天,我们就用最熟悉的 JavaScript,不讲废话,只讲关键逻辑,一步一步实现一个完整的「单向链表」结构,并配套一些典型操作,让你彻底掌握它!
📦 一、链表是啥?
链表(Linked List) 是一串节点(Node)的集合,每个节点包含:
- 当前值
value - 指向下一个节点的指针
next
与数组不同:
| 特性 | 数组(Array) | 链表(LinkedList) |
|---|---|---|
| 访问方式 | 支持下标访问 O(1) | 顺序访问 O(n) |
| 插入删除 | 中间插入/删除慢 | 任意位置高效插入删除 |
| 内存分布 | 连续 | 不连续 |
🧱 二、手写一个单向链表(JavaScript)
✅ 1. 节点类定义
class ListNode {
constructor(value) {
this.value = value;
this.next = null;
}
}
✅ 2. 链表类定义
class LinkedList {
constructor() {
this.head = null;
}
// 尾部插入节点
append(value) {
const newNode = new ListNode(value);
if (!this.head) {
this.head = newNode;
return;
}
let curr = this.head;
while (curr.next) {
curr = curr.next;
}
curr.next = newNode;
}
// 打印链表
print() {
let curr = this.head;
const values = [];
while (curr) {
values.push(curr.value);
curr = curr.next;
}
console.log('链表内容:', values.join(' -> '));
}
// 删除指定值
delete(value) {
if (!this.head) return;
if (this.head.value === value) {
this.head = this.head.next;
return;
}
let curr = this.head;
while (curr.next && curr.next.value !== value) {
curr = curr.next;
}
if (curr.next) {
curr.next = curr.next.next;
}
}
}
🧪 三、运行结果
const list = new LinkedList();
list.append(1);
list.append(3);
list.append(5);
list.print(); // 输出:链表内容:1 -> 3 -> 5
list.delete(3);
list.print(); // 输出:链表内容:1 -> 5
✅ 链表基本操作你已经掌握!
⚠️ 四、常见易错点
| 错误场景 | 正确处理方式 |
|---|---|
| 删除节点时没有判断 head | 要单独判断 this.head |
while 循环忘了更新指针 | 一定要 curr = curr.next |
delete 逻辑遗漏尾节点情况 | curr.next 是否为空都要判断 |
🔄 五、拓展任务
你可以试试:
- 实现
insert(index, value)按索引插入节点 - 实现
reverse()链表反转(递归 + 迭代两种写法) - 用 TypeScript 实现强类型链表结构
🧩 总结一句话
单向链表是所有算法数据结构的基石,前端工程师掌握它,就能迈出走向算法专家的第一步!