菜单

算法

相关源文件

目的与范围

此页面记录了后端架构师应该理解的基本算法。算法是解决问题的分步过程或公式,对于优化系统性能、高效处理数据以及在后端系统中实现核心功能尤为重要。有关这些算法所操作的相关数据结构的信息,请参见数据结构

算法分类

算法可以根据其设计方法、应用领域或计算特性进行分类。理解这些分类有助于架构师为特定用例选择合适的算法。

来源: README.md36-61

排序算法

排序是许多后端系统中的一项基本操作,从数据库操作到搜索功能。不同的排序算法在时间复杂度、空间复杂度和稳定性方面具有不同的特性。

排序算法比较

算法平均时间复杂度最佳情况最坏情况空间复杂度稳定吗?备注
选择排序O(n²)O(n²)O(n²)O(1)实现简单但对于大型数据集效率低下
冒泡排序O(n²)O(n)O(n²)O(1)仅对接近有序的数据高效
插入排序O(n²)O(n)O(n²)O(1)对小型数据集高效
快速排序O(n log n)O(n log n)O(n²)O(log n)实践中非常快,常作为许多库的默认设置
归并排序O(n log n)O(n log n)O(n log n)O(n)性能可预测,用于Java的Arrays.sort对象排序
堆排序O(n log n)O(n log n)O(n log n)O(1)原地排序,保证O(n log n)时间
希尔排序O(n log n) 到 O(n²)O(n log n)O(n²)O(1)插入排序的改进版
计数排序O(n+k)O(n+k)O(n+k)O(k)当值范围k相对于n较小时效率高
桶排序O(n+k)O(n+k)O(n²)O(n+k)将元素分配到桶中,然后对桶进行排序
基数排序O(d*(n+k))O(d*(n+k))O(d*(n+k))O(n+k)按个位或字符排序

来源: README.md37-47

排序算法的可视化表示

Java排序工具

Java提供了几种内置的排序工具

  • Arrays.sort():对基本类型使用双轴快速排序,对对象使用改进的归并排序
  • Collections.sort():使用改进的归并排序算法(TimSort)
  • 自定义Comparator接口允许根据特定属性进行灵活排序

来源: README.md48-49

搜索算法

二分查找是一种高效的搜索算法,适用于已排序数组,时间复杂度为O(log n)。

来源: README.md48

布隆过滤器

布隆过滤器是一种节省空间的概率数据结构,用于测试一个元素是否是一个集合的成员。它常用于大规模数据去重。

主要特性

  • 节省空间但允许假阳性
  • 永不产生假阴性(如果它说“不在集合中”,则该元素肯定不存在)
  • 常用于缓存、数据库和网络应用程序,以减少昂贵的查找操作

来源: README.md50 README.md511-521

字符串比较算法

KMP算法

Knuth-Morris-Pratt (KMP) 算法是一种高效的字符串匹配算法,它利用模式串的信息来避免不必要的字符比较。

主要优势

  • 避免在输入文本中回溯
  • 时间复杂度为 O(n+m),其中 n 为文本长度,m 为模式长度
  • 特别适用于重复模式搜索

来源: README.md51-52

图遍历算法

深度优先搜索(DFS)和广度优先搜索(BFS)

DFS与BFS比较

特征DFSBFS
实现使用栈(或递归)使用队列
内存使用O(h),其中 h 为高度O(w),其中 w 为最大宽度
完整性对于无限图不完整已完成
最适合路径查找,拓扑排序最短路径(无权重)
用例循环检测,迷宫生成层序遍历,网络路由

来源: README.md53 README.md531

优化算法

贪心算法

贪婪算法在每一步做出局部最优选择,以期找到全局最优解。它们适用于以下情况:

  • 问题具有最优子结构
  • 局部最优选择能够导向全局最优解

常见示例

  • Kruskal's 和 Prim's 算法用于最小生成树
  • Dijkstra's 算法用于最短路径
  • Huffman 编码用于数据压缩

来源: README.md54

动态规划

动态规划通过将复杂问题分解为更简单的子问题并存储结果以避免重复计算来解决问题。

常见应用

  • 最短路径算法
  • 生物信息学中的序列比对
  • 资源分配问题
  • 文本对齐

来源: README.md57 README.md544-545

回溯与剪枝

回溯通过尝试选项并在达到无效状态时“回溯”来探索所有可能的解决方案。

应用程序

  • N皇后问题
  • 数独求解
  • 约束满足问题
  • 博弈树遍历

来源: README.md55-56

概率算法

朴素贝叶斯

朴素贝叶斯是一种基于贝叶斯定理的分类算法,假设预测器之间相互独立。

应用程序

  • 文本分类
  • 垃圾邮件过滤
  • 情感分析
  • 医疗诊断

来源: README.md58 README.md548-551

特定应用算法

推荐算法

推荐系统使用算法根据用户的偏好和行为模式向用户推荐相关项目。

实施注意事项

  • 大型用户群体的可扩展性
  • 处理冷启动问题
  • 平衡准确性和多样性

来源: README.md59 README.md557-558

图优化算法

最小生成树算法

最小生成树(MST)算法在连通的无向图中找到一个边子集,该子集连接所有顶点,且总边权重最小。

应用程序

  • 网络设计
  • 聚类分析
  • 电路设计
  • NP-难问题的近似算法

来源: README.md60

最短路径算法

最短路径算法寻找图中节点之间最有效的路径。

应用程序

  • 网络路由
  • 道路导航系统
  • 资源分配
  • 航班调度

来源: README.md61 README.md565

性能考量

为生产系统选择算法时,请考虑:

  1. 时间复杂度:运行时如何随输入大小缩放
  2. 空间复杂度:内存需求
  3. 数据特性:某些算法在特定数据分布下表现更好
  4. 硬件限制:CPU、内存和I/O限制
  5. 并行性:算法能否从并行处理中受益?

来源: README.md445-447

Java实现考虑

在基于Java的后端系统中实现算法时

  1. 尽可能利用内置实现

    • Collections.sort()用于集合排序
    • Arrays.sort()用于数组排序
    • Collections.binarySearch()用于已排序列表的搜索
  2. 对于性能关键的算法,考虑使用多线程能力,例如

    • ForkJoinPool用于分治算法
    • ExecutorService用于并行处理
    • Stream API用于数据管道操作
  3. 注意内存影响

    • Java中的对象开销
    • 基本类型的自动装箱/拆箱
    • 大数据集时的垃圾回收影响

来源: README.md504-507