数据结构
1. 线性数据结构
数组(Array)
-
定义:数组是一种固定大小的、元素类型相同的线性数据结构。元素在内存中是连续存储的,可以通过索引直接访问。
-
特点:
- 支持常数时间的随机访问(
O(1)
)。 - 固定大小,一旦定义不可改变。
- 插入和删除操作的时间复杂度较高,尤其是在中间位置。
- 支持常数时间的随机访问(
-
操作:
- 访问 :
array[i]
(常数时间) - 插入 :插入到指定位置(
O(n)
) - 删除 :删除指定位置的元素(
O(n)
)
- 访问 :
-
应用场景:
- 存储需要频繁访问的元素,如矩阵、表格数据。
- 实现其他数据结构,如栈、队列的基础。
链表(Linked List)
-
定义:链表是一种动态的数据结构,由一系列节点组成,每个节点包含数据和一个指向下一个节点的引用。
-
特点:
- 动态大小,适合频繁插入和删除操作。
- 不支持快速随机访问(访问时间复杂度为
O(n)
)。
-
操作:
- 插入 :在链表的任意位置插入元素(
O(1)
如果已知位置,O(n)
否则) - 删除 :删除链表中的元素(
O(1)
如果已知位置,O(n)
否则) - 访问 :遍历链表(
O(n)
)
- 插入 :在链表的任意位置插入元素(
-
应用场景:
- 实现动态大小的数据结构,如栈、队列。
- 用于实现图的邻接表表示。
栈(Stack)
-
定义:栈是一种遵循"后进先出"(LIFO)原则的数据结构。可以只在一端进行插入和删除操作。
-
特点:
- 支持
push
和pop
操作。 - 访问元素只能从栈顶进行。
- 支持
-
操作:
- push :将元素压入栈顶(
O(1)
) - pop :从栈顶弹出元素(
O(1)
) - peek :查看栈顶元素(
O(1)
)
- push :将元素压入栈顶(
-
应用场景:
- 函数调用管理(调用栈)。
- 表达式求值(后缀表达式计算)。
队列(Queue)
-
定义:队列是一种遵循"先进先出"(FIFO)原则的数据结构。元素从一端(队尾)插入,从另一端(队头)删除。
-
特点:
- 支持
enqueue
和dequeue
操作。 - 队列的插入和删除操作在两端进行。
- 支持
-
操作:
- enqueue :将元素入队(
O(1)
) - dequeue :从队头移除元素(
O(1)
) - peek :查看队头元素(
O(1)
)
- enqueue :将元素入队(
-
应用场景:
- 任务调度(操作系统中的任务队列)。
- 消息传递(消息队列)。
2. 树形数据结构
二叉树(Binary Tree)
-
定义:每个节点最多有两个子节点(左子节点和右子节点)的树结构。
-
特点:
- 适合表示层次结构。
- 支持递归遍历(前序、中序、后序)。
-
操作:
- 插入:将节点插入到树中(复杂度视树的类型而定)
- 删除:从树中删除节点(复杂度视树的类型而定)
- 遍历 :前序、中序、后序遍历(
O(n)
)
-
应用场景:
- 表达树形结构的数据,如文件系统、组织结构。
- 递归操作,如表达式树。
二叉搜索树(Binary Search Tree, BST)
-
定义:一种特殊的二叉树,其中每个节点的左子树中的所有节点值小于节点值,右子树中的所有节点值大于节点值。
-
特点:
- 支持快速查找、插入和删除操作(平均
O(log n)
)。 - 不平衡的情况下,最坏情况下操作时间复杂度为
O(n)
。
- 支持快速查找、插入和删除操作(平均
-
操作:
- 查找 :快速查找特定值(
O(log n)
) - 插入 :插入新节点(
O(log n)
) - 删除 :删除节点(
O(log n)
)
- 查找 :快速查找特定值(
-
应用场景:
- 实现高效的动态集合,如字典、集合。
堆(Heap)
-
定义:完全二叉树的一种特殊形式,其中每个节点的值都大于(或小于)其子节点的值。
-
特点:
- 最大堆(Max Heap):根节点是最大值。
- 最小堆(Min Heap):根节点是最小值。
- 支持高效的最大值/最小值提取和排序操作。
-
操作:
- 插入 :将新元素插入堆中(
O(log n)
) - 删除 :删除堆顶元素(
O(log n)
) - 堆化 :调整堆的结构(
O(n)
)
- 插入 :将新元素插入堆中(
-
应用场景:
- 实现优先队列。
- 堆排序算法。
红黑树(Red-Black Tree)
-
定义:一种自平衡的二叉搜索树,每个节点有颜色属性(红色或黑色),并遵循一定的平衡规则。
-
特点:
- 保持树的平衡,保证操作的时间复杂度为
O(log n)
。 - 颜色属性帮助维持树的平衡。
- 保持树的平衡,保证操作的时间复杂度为
-
操作:
- 查找 :高效的查找操作(
O(log n)
) - 插入 :插入节点时进行调整(
O(log n)
) - 删除 :删除节点时进行调整(
O(log n)
)
- 查找 :高效的查找操作(
-
应用场景:
- 高效实现动态集合,如
TreeMap
和TreeSet
。
- 高效实现动态集合,如
B树和B+树
-
定义:自平衡的树数据结构,广泛应用于数据库和文件系统中。B树的每个节点可以有多个子节点,B+树在B树的基础上进一步优化了范围查询。
-
特点:
- 支持高效的范围查询和磁盘存储。
- 节点可以有多个子节点。
-
操作:
- 查找 :高效的查找操作(
O(log n)
) - 插入 :动态调整树结构(
O(log n)
) - 删除 :动态调整树结构(
O(log n)
)
- 查找 :高效的查找操作(
-
应用场景:
- 数据库索引。
- 文件系统目录结构。
Trie(前缀树)
-
定义:一种树形数据结构,用于存储字符串集合,支持高效的前缀查找。
-
特点:
- 支持快速的字符串前缀匹配。
- 节点表示字符,路径表示字符串。
-
操作:
- 插入 :插入字符串(
O(m)
,其中m
为字符串的长度) - 查找 :查找字符串(
O(m)
) - 前缀查询 :查找以特定前缀开始的所有字符串(
O(k)
,其中k
为前缀的长度)
- 插入 :插入字符串(
-
应用场景:
- 实现字典、自动补全。
- 拼写检查。
3. 图形数据结构
图(Graph)
-
定义:由节点(顶点)和边(连接节点的线)组成的数据结构。
-
特点:
- 图的边可以是有向的或无向的。
- 图的边可以有权重,也可以没有。
-
操作:
- 查找 :查找节点和边(
O(n + e)
,其中e
为边的数量) - 遍历 :广度优先搜索(BFS)、深度优先搜索(DFS)(
O(n + e)
)
- 查找 :查找节点和边(
-
应用场景:
- 网络分析(如社交网络、计算机网络)。
- 路径查找(如地图导航)。
图的表示
- 邻接矩阵(Adjacency Matrix)
:
-
定义 :用二维数组表示图的边。如果存在从节点
i
到节点j
的边,则matrix[i][j]
为true
或权重值,否则为false
或0
。 -
邻接表(Adjacency List):
- 定义:用链表表示每个节点的邻接节点。每个节点维护一个链表,其中存储它所有直接连接的邻居。
-
特点:
- 邻接矩阵 :适合稠密图,边的查找时间复杂度为
O(1)
。 - 邻接表 :适合稀疏图,边的查找时间复杂度为
O(n)
。
- 邻接矩阵 :适合稠密图,边的查找时间复杂度为
4. 哈希数据结构
哈希表(Hash Table)
-
定义:使用哈希函数将键映射到数组中的索引,用于快速查找、插入和删除。
-
特点:
- 平均时间复杂度为
O(1)
的查找、插入和删除操作。 - 处理哈希冲突的方法包括开放定址法、链式哈希法等。
- 平均时间复杂度为
-
操作:
- 插入 :将键值对插入哈希表(
O(1)
) - 查找 :根据键查找对应的值(
O(1)
) - 删除 :删除指定键的值(
O(1)
)
- 插入 :将键值对插入哈希表(
-
应用场景:
- 实现集合、映射,如
HashMap
和HashSet
。
- 实现集合、映射,如
5. 其他数据结构
跳表(Skip List)
-
定义:通过多层链表加速元素的查找,每一层链表都包含部分元素,并且每一层的链表都是升序的。
-
特点:
- 支持快速的查找、插入和删除操作(
O(log n)
)。 - 较为简单的实现,适合在内存中使用。
- 支持快速的查找、插入和删除操作(
-
操作:
- 查找 :查找元素(
O(log n)
) - 插入 :插入元素(
O(log n)
) - 删除 :删除元素(
O(log n)
)
- 查找 :查找元素(
-
应用场景:
- 替代平衡树的数据结构,如
Skip List
。
- 替代平衡树的数据结构,如
位图(Bitmap)
-
定义:用于表示布尔值集合的数据结构,其中每一位代表一个布尔值。
-
特点:
- 节省空间,适合处理大规模数据集的位级操作。
- 支持快速的位操作,如集合的并、交、差等操作。
-
操作:
- 设置位 :设置指定位置的位为1(
O(1)
) - 清除位 :设置指定位置的位为0(
O(1)
) - 查询位 :查询指定位置的位的值(
O(1)
)
- 设置位 :设置指定位置的位为1(
-
应用场景:
- 实现布隆过滤器。
- 高效的集合操作和数据处理。
集合(Set)
-
定义:存储唯一元素的集合,不允许重复元素。
-
特点:
- 可以用哈希表、红黑树等实现。
- 提供基本的集合操作,如并集、交集、差集等。
-
操作:
- 添加元素 :将元素添加到集合(
O(1)
或O(log n)
,取决于实现) - 删除元素 :从集合中删除元素(
O(1)
或O(log n)
) - 查找元素 :检查元素是否在集合中(
O(1)
或O(log n)
)
- 添加元素 :将元素添加到集合(
-
应用场景:
- 去重操作,如去重列表。
- 实现数学集合的操作和查询。
通过理解不同数据结构的定义、特点和应用场景,你可以选择合适的数据结构来优化程序的性能和效率。不同的数据结构在处理不同类型的数据和操作时表现出不同的优劣势,选择合适的数据结构是编程中的一个重要技巧。