Files
test-repo/docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md
T
sanbuphy 3af119a598 feat(appendix): 添加多个交互式演示组件,完善 AI/Infra 等章节内容
- 新增 Vibe Coding 全栈相关演示组件 (DeveloperSkillShift, FrontendTriad, BackendCore 等)
- 新增 RAG 相关组件 (RAGPipeline, ChunkingStrategy, Retrieval 等)
- 新增 Embedding & Vector 相关组件 (EmbeddingConcept, VectorSimilarity 等)
- 新增 AI Native App 设计组件 (AINativeArch, PromptDesign 等)
- 新增 Infrastructure as Code 组件 (IaCConcept, TerraformWorkflow 等)
- 新增 DNS & HTTPS 演示组件 (DnsResolution, HttpsHandshake 等)
- 新增 Model Finetuning 组件 (FinetuningPipeline 等)
- 更新多个章节的 markdown 内容,集成交互式演示
2026-02-24 18:22:58 +08:00

8.0 KiB
Raw Blame History

算法思维入门

::: tip 前言 如何高效地解决问题? 你可能遇到过这样的困惑:同一个问题,有人写的代码跑几秒就出结果,有人写的跑几分钟还在转。差别往往在于算法。本章带你理解算法的核心思维方式。 :::

这篇文章会带你学什么?

学完这章后,你将获得:

  • 问题拆解能力:面对复杂问题,能想到用分治、递归等策略拆解,而不是一上来就写代码
  • 效率判断能力:用大 O 表示法判断两种解法哪个更高效,而不是凭感觉猜测
  • 复杂度思维:写代码前先估算数据规模和时间要求,选择合适的算法级别
  • 后续学习基础:为高级数据结构、分布式系统、机器学习打下基础
章节 内容 核心概念
第 1 章 二分查找 分治思想、O(log n)
第 2 章 排序算法 冒泡、快排、归并
第 3 章 复杂度分析 时间复杂度、空间复杂度

0. 全景图:算法是什么?

想象你要在一本字典里找一个单词:

  • 方法一:从第一页开始,一页一页翻(线性查找)
  • 方法二:根据首字母定位,再二分查找(二分查找)

两种方法都能找到,但效率天差地别。算法就是解决问题的方法

算法的核心指标:

指标 含义 为什么重要
时间复杂度 运行时间随数据量增长的趋势 预测大规模数据的性能
空间复杂度 内存占用随数据量增长的趋势 评估内存消耗
正确性 是否总能得到正确结果 算法的基本要求

::: tip 📊 逐行解读这张表 时间复杂度:用大 O 表示法描述。O(n) 表示数据量翻倍,时间翻倍;O(n²) 表示数据量翻倍,时间变成 4 倍。

空间复杂度:同样用大 O 表示法。有些算法用空间换时间(如哈希表),有些用时间换空间(如压缩算法)。

正确性:算法必须对所有可能的输入都能给出正确结果。边界条件(空输入、极大输入)最容易出错。 :::


1. 二分查找:每次排除一半

1.1 二分查找的原理

::: tip 💡 二分查找如何工作? 前提:数据必须有序

过程

  1. 找到中间元素
  2. 如果中间元素等于目标,找到!
  3. 如果目标小于中间元素,在左半部分继续
  4. 如果目标大于中间元素,在右半部分继续
  5. 每次排除一半,直到找到或确定不存在

时间复杂度O(log n)

生活类比:猜数字游戏。我想一个 1-100 的数,你每次猜中间,我告诉你大了还是小了。最多猜 7 次就能猜中(因为 2⁷ = 128 > 100)。 :::

1.2 为什么二分查找这么快?

数据量 线性查找 二分查找
100 100 次 7 次
1,000 1,000 次 10 次
1,000,000 1,000,000 次 20 次
1,000,000,000 1,000,000,000 次 30 次

::: tip 💡 对数增长的威力 二分查找的时间复杂度是 O(log n),这意味着:

  • 10 亿数据,最多查找 30 次
  • 1 万亿数据,最多查找 40 次

这就是对数增长的威力——数据量增加 1000 倍,查找次数只增加 10 次。 :::


2. 排序:将无序变有序

2.1 常见排序算法

算法 时间复杂度 特点 适用场景
冒泡排序 O(n²) 简单但慢 教学、小数据量
选择排序 O(n²) 简单但慢 小数据量
插入排序 O(n²) 对近乎有序的数据快 小数据、近乎有序
快速排序 O(n log n) 实际最快 通用排序
归并排序 O(n log n) 稳定排序 需要稳定性的场景
堆排序 O(n log n) 原地排序 内存受限场景

2.2 为什么快速排序"快"

::: tip 💡 快速排序的原理 核心思想:分治法

  1. 选一个"基准"元素
  2. 把比基准小的放左边,比基准大的放右边
  3. 对左右两部分递归排序
  4. 合并结果

为什么快?

  • 每次划分后,基准元素就到了最终位置
  • 平均情况下,每次划分大约排除一半元素
  • 时间复杂度 O(n log n)

生活类比:整理书架。先抽出一本书,把比它薄的放左边,比它厚的放右边。然后对左右两堆分别重复这个过程。 :::


3. 递归:自己调用自己

3.1 递归的本质

::: tip 💡 什么是递归? 递归是函数调用自身的编程技巧。

两个关键要素

  1. 基本情况:什么时候停止递归?
  2. 递归步骤:如何把问题分解成更小的子问题?

经典例子:阶乘

function factorial(n) {
  if (n <= 1) return 1        // 基本情况
  return n * factorial(n - 1) // 递归步骤
}

生活类比:俄罗斯套娃。打开一个娃娃,里面是更小的娃娃,直到最小的那个打不开为止。 :::

3.2 递归 vs 迭代

特性 递归 迭代(循环)
代码简洁度 通常更简洁 可能更复杂
内存消耗 较高(调用栈) 较低
性能 稍慢(函数调用开销) 更快
适用场景 树遍历、分治算法 简单重复任务

::: warning ⚠️ 递归的陷阱 栈溢出:递归层次太深,调用栈空间耗尽。

解决方法

  • 改用迭代
  • 使用尾递归优化(某些语言支持)
  • 限制递归深度 :::

4. 贪心算法:每步选最优

4.1 贪心的思想

::: tip 💡 什么是贪心算法? 贪心算法在每一步都选择当前看起来最优的选择,希望最终得到全局最优解。

适用条件

  1. 贪心选择性质:局部最优能导致全局最优
  2. 最优子结构:问题的最优解包含子问题的最优解

经典例子:硬币找零

  • 目标:用最少的硬币凑出指定金额
  • 贪心策略:每次选最大的硬币
  • 结果:67 元 = 50 + 10 + 5 + 1 + 15 枚)

生活类比:登山时,每次都选最陡的路往上走。虽然不一定能到最高峰,但通常能到不错的位置。 :::

4.2 贪心的局限性

::: warning ⚠️ 贪心不一定得到最优解 反例:硬币找零

如果硬币面值是 [1, 3, 4],要凑 6 元:

  • 贪心:4 + 1 + 1 = 3 枚
  • 最优:3 + 3 = 2 枚

贪心算法在这里失败了!

教训:贪心算法简单高效,但不总是能得到最优解。使用前要证明问题满足贪心条件。 :::


5. 算法设计范式

范式 思想 典型算法 适用问题
分治 把问题分解成小问题 快速排序、归并排序 可分解的问题
贪心 每步选最优 最小生成树、霍夫曼编码 有贪心性质的问题
动态规划 记录子问题的解 背包问题、最短路径 有重叠子问题
回溯 试错,走不通就回退 八皇后、全排列 搜索问题

6. 总结:算法是解决问题的艺术

让我们用一个比喻总结各种算法思想:

思想 比喻 核心要点
二分查找 猜数字 每次排除一半
排序 整理书架 建立秩序
递归 俄罗斯套娃 化大为小
贪心 登山选路 局部最优

::: tip 💡 核心启示 算法的本质是"效率"和"正确性"的平衡。

  • 好的算法能让程序效率提升几个数量级
  • 但过度优化可能引入复杂性
  • 先保证正确,再追求效率

理解算法思维,比记住具体算法更重要:

  • 分治:把大问题分解成小问题
  • 贪心:每步选最优
  • 动态规划:记录子问题的解
  • 回溯:试错,走不通就回退 :::

延伸阅读

  • 算法导论:系统学习算法的经典教材
  • LeetCode:通过刷题提升算法能力
  • 算法可视化:直观理解算法执行过程
  • 竞赛算法:学习更高级的算法技巧