一、线性数据结构:基础但不可或缺
-
数组(Array)
数组是最基础的连续内存数据结构,支持随机访问(O(1)时间复杂度),但插入/删除需移动元素(O(n))。
应用场景:存储固定大小数据、快速索引访问(如矩阵运算)。
优化建议:动态数组(如C++的vector)通过倍增策略降低扩容成本。 -
链表(Linked List)
链表通过指针串联节点,支持O(1)插入/删除,但随机访问需遍历(O(n))。
变种:单向链表、双向链表、循环链表。
代码示例(单向链表插入):void insertAtHead(Node** head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = *head;*head = newNode;}
-
栈(Stack)
后进先出(LIFO)结构,支持push、pop、peek操作。
应用场景:函数调用栈、表达式求值、括号匹配。
实现方式:数组或链表均可,需注意栈溢出风险。 -
队列(Queue)
先进先出(FIFO)结构,支持enqueue、dequeue操作。
变种:双端队列(Deque)、优先队列(堆实现)。
应用场景:任务调度、广度优先搜索(BFS)。 -
哈希表(Hash Table)
通过哈希函数将键映射到数组索引,支持平均O(1)的插入、删除、查找。
冲突处理:链地址法、开放寻址法。
优化建议:选择优质哈希函数,动态调整表大小以维持负载因子。
二、树形结构:层级数据的天然表达
-
二叉树(Binary Tree)
每个节点最多有两个子节点的树结构。
遍历方式:前序、中序、后序、层序遍历。
应用场景:表达式解析、目录结构表示。 -
二叉搜索树(BST)
左子树节点值<根节点值<右子树节点值,支持O(log n)的搜索、插入、删除(平衡时)。
平衡策略:AVL树、红黑树。
代码示例(BST插入):Node* insert(Node* root, int key) {if (!root) return newNode(key);if (key < root->key) root->left = insert(root->left, key);else root->right = insert(root->right, key);return root;}
-
堆(Heap)
完全二叉树,分为最大堆(父节点≥子节点)和最小堆。
应用场景:优先队列、Top K问题、堆排序。
操作复杂度:插入/删除O(log n),取极值O(1)。 -
Trie树(前缀树)
用于高效存储和检索字符串集合,支持前缀匹配。
应用场景:自动补全、IP路由表。
空间优化:压缩Trie减少节点数量。 -
B树与B+树
多路平衡搜索树,支持磁盘存储的高效访问。
应用场景:数据库索引、文件系统。
B+树优势:所有数据存储在叶子节点,支持范围查询。
三、图结构:复杂关系的建模工具
-
无向图与有向图
无向图边无方向,有向图边有方向(如网页链接)。
表示方法:邻接矩阵(稠密图)、邻接表(稀疏图)。 -
深度优先搜索(DFS)
沿一条路径尽可能深搜索,用于连通性检测、拓扑排序。
实现方式:递归或显式栈。 -
广度优先搜索(BFS)
按层遍历,用于最短路径(无权图)、社交网络好友推荐。
优化建议:使用队列并标记已访问节点。 -
Dijkstra算法
求解单源最短路径(带权非负图),基于贪心策略。
时间复杂度:O((V+E) log V)(优先队列优化后)。 -
Floyd-Warshall算法
求解所有节点对最短路径(可处理负权边),动态规划实现。
空间复杂度:O(V²),适合小规模图。
四、排序与搜索:高效处理数据的基石
-
快速排序
分治思想,平均O(n log n),最坏O(n²)(需随机化主元避免)。
优化技巧:三数取中法选主元,小数组切换插入排序。 -
归并排序
稳定排序,O(n log n)时间复杂度,但需O(n)额外空间。
应用场景:外部排序、链表排序。 -
二分查找
在有序数组中查找目标值,时间复杂度O(log n)。
变种:查找第一个/最后一个等于目标的位置。
代码示例:def binary_search(arr, target):left, right = 0, len(arr)-1while left <= right:mid = (left + right) // 2if arr[mid] == target: return midelif arr[mid] < target: left = mid + 1else: right = mid - 1return -1
-
KMP算法
字符串匹配算法,预处理模式串构建部分匹配表,匹配阶段O(n)。
核心思想:利用已匹配前缀避免重复比较。 -
动态规划
解决具有重叠子问题和最优子结构的问题(如斐波那契数列、背包问题)。
实现步骤:定义状态、状态转移方程、初始化与边界条件。
代码示例(0-1背包问题):def knapsack(weights, values, capacity):dp = [[0]*(capacity+1) for _ in range(len(weights)+1)]for i in range(1, len(weights)+1):for w in range(1, capacity+1):if weights[i-1] <= w:dp[i][w] = max(dp[i-1][w], values[i-1] + dp[i-1][w-weights[i-1]])else:dp[i][w] = dp[i-1][w]return dp[-1][-1]
五、总结与建议
掌握这20个数据结构与算法,需结合理论理解与实战练习。建议从以下方面入手:
- 分阶段学习:先掌握线性结构与基础排序,再逐步深入树、图与高级算法。
- 代码实现:通过LeetCode等平台刷题,强化动手能力。
- 性能分析:关注时间复杂度与空间复杂度,理解不同场景下的最优选择。
- 工程应用:例如在分布式系统中,哈希表可用于数据分片,B+树优化索引查询。
通过系统学习与实践,开发者能够构建更高效、稳定的系统,应对复杂业务场景的挑战。