菜单

数据结构

相关源文件

本文档提供了算法问题解决中常用数据结构的全面概述。它涵盖了各种数据结构的基本概念、实现细节和实际应用,作为理解 LeetCode 仓库中算法构建块的参考指南。有关使用这些数据结构的特定算法的信息,请参阅 算法

数据结构分类

数据结构根据数据组织方式可分为两大类

来源: thinkings/basic-data-structure.md7-12

线性数据结构

线性数据结构按顺序组织元素,其中每个元素(第一个和最后一个除外)恰好有一个前驱和一个后继。

数组

数组将元素存储在连续的内存位置中,允许按索引进行 O(1) 时间访问。

主要特性

  • O(1) 时间的随机访问
  • 许多语言中的固定大小
  • 许多其他数据结构的基础

实际应用:React Hooks 内部使用数组来管理组件状态

来源: thinkings/basic-data-structure.md13-68

栈遵循后进先出 (LIFO) 原则,元素只能从顶部添加或移除。

关键操作

  • push(element):将元素添加到顶部 - O(1)
  • pop():移除并返回顶部元素 - O(1)
  • peek()/top():查看顶部元素而不移除 - O(1)

应用程序

  • 程序执行中的函数调用栈
  • 表达式求值(例如,括号匹配)
  • 浏览器历史记录管理
  • 撤销/重做功能

来源: thinkings/basic-data-structure.md128-178

队列

队列遵循先进先出 (FIFO) 原则,元素在队尾添加,在队头移除。

关键操作

  • enqueue(element):将元素添加到队尾 - O(1)
  • dequeue():移除并返回队头元素 - O(1)
  • front():查看队头元素而不移除 - O(1)

实际应用:HTTP 请求处理 HTTP/1.1 中的“队首阻塞”问题是由于同一 TCP 连接的请求按顺序处理造成的。HTTP/2 通过多路复用解决了这个问题

来源: thinkings/basic-data-structure.md70-127

链表

链表由节点组成,每个节点包含数据和指向下一个节点的引用。

类型

  • 单向链表:每个节点指向下一个节点
  • 双向链表:每个节点同时指向前一个和后一个节点
  • 循环链表:最后一个节点指向第一个节点

关键操作

  • 插入:在头部或尾部有引用时为 O(1),其他位置为 O(n)
  • 删除:有节点引用时为 O(1),查找节点为 O(n)
  • 查找:O(n)

实际应用:React Fiber React Fiber 使用基于链表的架构来实现虚拟组件树

来源: thinkings/basic-data-structure.md182-245

非线性数据结构

非线性数据结构将元素组织成层级或网络结构,允许元素拥有多个前驱和后继。

树是具有根节点和由边连接的子节点的层级结构。

关键术语

  • 根:最顶部的节点
  • 父/子:连接节点之间的关系
  • 叶子:没有子节点的节点
  • 深度:从根到节点的距离
  • 高度:从节点到叶子的最长路径的长度

重要属性

  • 具有 n 个节点的树恰好有 n-1 条边
  • 任意两个节点之间恰好有一条路径

来源: thinkings/basic-data-structure.md246-276

二叉树

二叉树是每个节点最多有两个子节点的树,通常称为左子节点和右子节点。

类型

  • 满二叉树:每个节点有 0 或 2 个子节点
  • 完全二叉树:除最后一层外,所有层都已填满
  • 完美二叉树:所有内部节点都有 2 个子节点,所有叶子都在同一层
  • 平衡二叉树:左右子树的高度差最多为 1

二叉树遍历

  1. 前序(根,左,右):A, B, D, E, C, F, G
  2. 中序(左,根,右):D, B, E, A, F, C, G
  3. 后序(左,右,根):D, E, B, F, G, C, A
  4. 层序(广度优先):A, B, C, D, E, F, G

实现方法

  • 递归遍历
  • 使用栈(用于 DFS)或队列(用于 BFS)的迭代遍历
  • 莫里斯遍历(常数空间)

来源: thinkings/binary-tree-traversal.md1-214 thinkings/basic-data-structure.md277-306

二叉搜索树 (BST)

二叉搜索树是满足以下排序属性的二叉树:

  • 节点的左子树仅包含键小于节点键的节点
  • 右子树仅包含键大于节点键的节点
  • 左子树和右子树也都是 BST

关键操作

  • 搜索:O(h),其中 h 是树的高度
  • 插入:O(h)
  • 删除:O(h)
  • 中序遍历产生排序输出

重要特征:二叉搜索树的中序遍历按排序顺序产生元素(1, 3, 4, 6, 7, 8, 10, 14)。

来源: thinkings/basic-data-structure.md330-355

平衡二叉树

平衡二叉树是 BST,旨在保持对数高度,确保操作性能为 O(log n)。

类型

  • AVL 树:高度平衡树,左右子树的高度差最多为 1
  • 红黑树:自平衡树,具有颜色属性,可确保对数高度

重新平衡操作

  • 旋转(左旋和右旋)
  • 颜色翻转(用于红黑树)

来源: thinkings/basic-data-structure.md356-382

堆是基于树的专用数据结构,它满足堆属性

  • 最大堆:每个父节点大于或等于其子节点
  • 最小堆:每个父节点小于或等于其子节点

关键操作

  • 插入:O(log n)
  • 提取最小值/最大值:O(log n)
  • 查看:O(1)
  • 堆化:O(n)

二叉堆通常实现为数组,其中索引 i 处的节点

  • 父节点:floor((i-1)/2)
  • 左子节点:2*i + 1
  • 右子节点:2*i + 2

应用程序

  • 优先队列
  • 堆排序
  • 图算法(Dijkstra, Prim)
  • 查找第 k 大/小元素

来源: thinkings/basic-data-structure.md307-329

字典树 (前缀树)

Trie(发音同 "try")是一种优化的树状数据结构,用于字符串操作,特别是前缀搜索。

关键操作

  • 插入:O(m),其中 m 是键的长度
  • 搜索:O(m)
  • 前缀搜索:O(m)

实现

应用程序

  • 自动补全和预测文本
  • 拼写检查器
  • IP路由(最长前缀匹配)
  • 文字游戏

来源: thinkings/trie.md1-296 problems/208.implement-trie-prefix-tree.md1-196

图由顶点(节点)和连接它们的边组成,表示对象之间的关系。

类型

  • 有向 vs 无向:边是否具有方向
  • 带权 vs 不带权:边是否有权重
  • 有环 vs 无环:是否包含环
  • 连通 vs 不连通:所有顶点是否可以从任何其他顶点到达

图的表示

  1. 邻接矩阵:二维数组,其中 matrix[i][j] 表示从 i 到 j 的边
  2. 邻接表:列表数组,其中 list[i] 包含与 i 相邻的顶点

图的遍历

  • 深度优先搜索 (DFS):在回溯之前尽可能深地探索每个分支
  • 广度优先搜索 (BFS):在移至下一层之前探索当前深度的所有邻居

常用图算法

  • 最短路径:Dijkstra, Bellman-Ford, Floyd-Warshall
  • 最小生成树:Kruskal, Prim
  • 拓扑排序(用于 DAG)
  • 强连通分量

来源: thinkings/graph.md1-896

时间和空间复杂度比较

数据结构访问搜索插入删除Space键
数组O(1)O(n)O(n)O(n)O(n)
链表O(n)O(n)O(1)*O(1)*O(n)
O(n)O(n)O(1)O(1)O(n)
队列O(n)O(n)O(1)O(1)O(n)
二叉搜索树(平衡)O(log n)O(log n)O(log n)O(log n)O(n)
二叉搜索树(不平衡)O(n)O(n)O(n)O(n)O(n)
O(1)**O(n)O(log n)O(log n)O(n)
Trie树O(m)O(m)O(m)O(m)O(n×m)
图(邻接表)O(n)O(n)O(1)O(n+e)O(n+e)
图(邻接矩阵)O(1)O(1)O(1)O(1)O(n²)

*引用节点 **仅用于获取最小值/最大值 n:元素数量,m:键长,e:边数

来源:合并多个文件

数据结构选择指南

选择正确的数据结构取决于所需的操作及其频率。

来源:合并多个文件

实际应用

数据结构应用程序
数组存储和访问顺序数据、矩阵运算、动态规划
函数调用管理、表达式求值、撤销机制、浏览器历史记录
队列任务调度、CPU 调度、打印机队列、HTTP 请求处理
链表React Fiber 实现、音乐播放列表、Web 浏览器缓存、撤销功能
文件系统、组织层级、HTML DOM、数据库索引
BST数据库索引、关联数组实现、数据优先级排序
优先队列、调度算法、堆排序、图算法
Trie 树自动补全系统、拼写检查器、IP 路由、搜索引擎建议
社交网络、地图和导航、依赖项解析、网络路由

来源:合并多个文件

LeetCode 问题中的常见数据结构操作

此仓库实现了 LeetCode 问题中常用的各种数据结构操作

通过理解这些基本的数据结构及其操作,您将能够有效地解决各种算法问题。