📡 喜欢这篇文章?通过 RSS 订阅更新

数据结构学习笔记

| 加载中...

为什么学数据结构

写代码能跑 ≠ 代码写得好。数据结构选对了,性能可能差十倍、百倍。面试也会考,但更重要的是日常开发中做技术决策时不抓瞎。

数组 (Array)

最基础的结构,连续内存存储,下标随机访问 O(1)。

const arr = [1, 2, 3];
arr.push(4);     // O(1) 均摊
arr.unshift(0);  // O(n) 要移动所有元素
arr[2];          // O(1) 随机访问

适合: 读多写少、已知大小、需要随机访问的场景。


链表 (Linked List)

每个节点存值 + 指向下个节点的引用,不连续存储。

class Node {
  constructor(val, next = null) {
    this.val = val;
    this.next = next;
  }
}

const list = new Node(1, new Node(2, new Node(3)));
操作数组链表
随机访问O(1)O(n)
头部插入O(n)O(1)
尾部插入O(1) 均摊O(1)(有尾指针时)
中间插入O(n)O(1)(已知位置时)

适合: 频繁插入删除、不需要随机访问的场景。LRU 缓存、浏览器前进后退都用它。


栈 (Stack)

后进先出(LIFO),就两件事:压入和弹出。

const stack = [];
stack.push(1);
stack.push(2);
stack.pop(); // 2

应用场景:

  • 函数调用栈(递归的本质)
  • 括号匹配
  • 撤销/重做功能
  • 浏览器历史记录

队列 (Queue)

先进先出(FIFO),一头进一头出。

// JS 没有原生队列,数组模拟即可
const queue = [];
queue.push(1); // 入队
queue.push(2);
queue.shift(); // 出队 → 1

应用场景:

  • 广度优先搜索(BFS)
  • 任务调度
  • 消息队列

进阶:优先队列(Priority Queue),出队顺序按优先级而非先进先出。JS 里可用最小堆实现,或直接用排序数组(数据量小时够用)。


哈希表 (Hash Table)

键值对存储,通过哈希函数直接定位,平均 O(1) 读写。

const map = new Map();
map.set('name', 'resigned');
map.get('name'); // O(1)

const obj = { name: 'resigned' };
obj['name']; // 也是哈希表的思路

核心问题:哈希冲突。 常见解法:

  • 拉链法:冲突的位置挂链表(Java HashMap 的做法)
  • 开放寻址法:冲突了就找下一个空位

注意: 最坏情况退化到 O(n)(所有 key 都冲突时),但概率极低。


树 (Tree)

二叉搜索树(BST)

左子树 < 根 < 右子树,中序遍历得到有序序列。

     5
    / \
   3   8
  / \   \
 1   4   9
  • 查找/插入/删除:平均 O(log n),最坏 O(n)(退化为链表)

平衡二叉树

为了防止退化,引入自平衡机制(AVL 树、红黑树)。红黑树是 Java TreeMap、C++ std::map 的底层实现。

堆(Heap)

特殊的完全二叉树,分为最大堆和最小堆。

// 最小堆 — JavaScript 没有原生堆,手写或用库
// 用途:优先队列、Top K 问题、堆排序

关键操作:

  • 插入:O(log n)
  • 取极值:O(log n)
  • 查看极值:O(1)

图 (Graph)

由节点(顶点)和边组成,比树更通用(允许环、多对多关系)。

两种存储方式:

// 邻接矩阵 — 适合稠密图
const matrix = [
  [0, 1, 1],
  [1, 0, 0],
  [1, 0, 0],
];

// 邻接表 — 适合稀疏图,更常用
const graph = {
  A: ['B', 'C'],
  B: ['A'],
  C: ['A'],
};

两种遍历:

  • BFS(广度优先):用队列,适合找最短路径
  • DFS(深度优先):用栈/递归,适合连通性检测、拓扑排序

应用: 社交网络、导航路线、依赖管理(npm install 的依赖树就是个 DAG)。


复杂度速查

数据结构访问查找插入删除
数组O(1)O(n)O(n)O(n)
链表O(n)O(n)O(1)O(1)
O(n)O(n)O(1)O(1)
队列O(n)O(n)O(1)O(1)
哈希表O(1)O(1)O(1)
BSTO(log n)O(log n)O(log n)O(log n)
O(n)O(n)O(log n)O(log n)

学习建议

  1. 不要背代码,理解原理更重要。面试时能说出思路比默写实现有价值。
  2. 自己手写一遍经典结构(链表、BST、哈希表),写一次比看十遍管用。
  3. 刷题时归类:看到「最短路径」→ BFS,「括号匹配」→ 栈,「Top K」→ 堆。建立条件反射。
  4. 日常开发中有意识地选型:需要快速查找?Map。需要有序?排序数组或 BST。需要频繁首尾操作?Deque。

学数据结构不是为了面试,是为了在写代码的时候脑子里有更多选择。

// Comments

💬 访客留言

无需登录,直接留言 👇

我的歌单 0
歌曲
歌词

--

--

-/-
0:00
0:00

loading...

我的歌单 --