算法思维入门:从二分搜索到分治——easy-vibe 计算机基础附录精讲
算法思维入门从二分搜索到分治——easy-vibe 计算机基础附录精讲【免费下载链接】easy-vibe vibe coding 101The first course for AI-native product builders.项目地址: https://gitcode.com/GitHub_Trending/ea/easy-vibe本文基于 easy-vibe 开源项目vibe coding 101面向 AI 原生产品构建者的第一门课日文版文档 docs/ja-jp/appendix/1-computer-fundamentals/algorithm-thinking.md 编写是该课程计算机基础附录中关于算法思维的核心章节。文章完整继承原文档的概念、对照表、代码示例与实操演示并补充复杂度分析、可运行的算法实现与仓库内的关联学习路径帮助 AI 时代的开发者建立可迁移的算法心智。你能从本文获得什么问题分解能力面对复杂问题不再急于动手写代码而是用分治、递归等策略先拆解问题效率判断能力用大 O 记法判断两个方案哪个更高效告别凭感觉猜计算量思维写代码之前先估算数据规模与时间需求选择合适量级的算法后续学习基础为高级数据结构、分布式系统、机器学习等内容打好地基。章节内容核心概念第 1 章二分搜索分治思想、O(log n)第 2 章排序算法冒泡排序、快速排序、归并排序第 3 章复杂度分析时间复杂度、空间复杂度0. 全景图算法的本质是什么想象在词典里查一个词方法 1从第一页开始一页一页翻线性搜索方法 2先按首字母定位到章节再在章节内二分查找二分搜索。两种方法都能找到但效率天差地别。算法就是解决问题的方法——同样的输入不同的方法决定了是几秒出结果还是几分钟还在转。算法的三个核心指标指标含义为什么重要时间复杂度数据量增长时运行时间如何增长预测大规模数据下的性能空间复杂度数据量增长时内存占用如何增长评估内存消耗正确性是否总能得到正确结果算法的基本要求逐项说明时间复杂度用大 O 记法描述。O(n) 表示数据量翻倍、时间也翻倍O(n²) 表示数据量翻倍、时间变为 4 倍。空间复杂度同样使用大 O 记法。有的算法用空间换时间如哈希表有的用时间换空间如压缩算法。正确性要求算法对所有可能的输入都给出正确结果。边界条件——空输入、超大输入——恰恰是最容易出错的环节。在 easy-vibe 仓库中本章通过AlgorithmDemo /交互组件在文档站点中呈现搜索对比演示从仓库 docs 目录结构可以确认同一章节在 ar-sa、de-de、en、es-es、fr-fr、ja-jp、ko-kr、vi-vn、zh-cn、zh-tw 共 10 种语言版本中保持完全一致的内容骨架便于多语言学习者对照阅读参见 docs/en/appendix/1-computer-fundamentals/algorithm-thinking.md、docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md。1. 二分搜索每次排除一半1.1 二分搜索的原理前提数据必须是已排序的。执行步骤找到中间元素中间元素等于目标值——找到了目标值小于中间元素——继续在左半部分查找目标值大于中间元素——继续在右半部分查找每次都排除一半直到找到目标或确认不存在。时间复杂度O(log n)。生活类比猜数字游戏。我心中想一个 1100 的数字你每次都猜中间值我回答大了/小了。最多 7 次就能猜中——因为 2⁷ 128 100。一个标准的 JS 实现如下对应原文档每次排除一半的步骤描述function binarySearch(sortedArr, target) { let left 0 let right sortedArr.length - 1 while (left right) { const mid Math.floor((left right) / 2) // 步骤 1找中间元素 if (sortedArr[mid] target) return mid // 步骤 2命中 if (target sortedArr[mid]) { right mid - 1 // 步骤 3去左半部分 } else { left mid 1 // 步骤 4去右半部分 } } return -1 // 步骤 5不存在 }原文档通过SearchAlgorithmDemo /组件提供可交互演示你可以在线选择线性搜索 / 二分搜索对比两者的执行过程该组件由文档站点的前端渲染层提供各语言版本文档中以同一组件标签引用。1.2 二分搜索的性能原理数据量线性搜索二分搜索100100 次7 次1,0001,000 次10 次1,000,0001,000,000 次20 次1,000,000,0001,000,000,000 次30 次逐列解读第 1 列数据量从 100 一路增长到 10 亿扩大了 1000 万倍第 2 列线性搜索最笨的方法从头到尾逐个找搜索次数等于数据量第 3 列二分搜索聪明的方法每次排除一半搜索次数只与数据量的对数相关——10 亿数据也只要 30 次对比结论数据量达到 100 万时线性搜索要 100 万次二分搜索只要 20 次——差距高达 5 万倍。对数增长的威力二分搜索的时间复杂度是 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)原地排序有内存约束的场景逐项解读冒泡排序像水底的泡泡不断上浮是最基础的排序算法。容易理解但速度最慢。适合学习排序思想不适合实战。选择排序每次都选出最小的放到前面。同样简单但无论数据是否有序比较次数都一样。插入排序像整理手中的扑克牌把每张牌插入到前面已排好的部分。对近乎有序的数据效率很高。快速排序实际开发中最常用的排序。平均情况下最快但最坏情况数据已经有序会退化到 O(n²)。归并排序采用分治思想始终是 O(n log n)但需要额外空间。适合要求稳定性的场景。堆排序基于堆这种数据结构是原地排序不需要额外空间但实际运行速度通常比快速排序慢。2.2 快速排序的性能原理核心思想分治法。选取一个基准pivot元素把比基准小的放左边比基准大的放右边递归地对左右两部分排序合并结果。为什么快每次分区后基准元素就到达了它的最终位置平均情况下每次分区大约排除一半元素时间复杂度 O(n log n)。生活类比整理书架。先抽出一本书比它薄的放左边、比它厚的放右边然后对左右两堆重复同样的操作。参考实现分区思路对应原文档 4 个步骤function quickSort(arr) { if (arr.length 1) return arr // 递归出口 const pivot arr[Math.floor(arr.length / 2)] // 步骤 1选基准 const left [], right [] for (let i 0; i arr.length; i) { if (i Math.floor(arr.length / 2)) continue if (arr[i] pivot) left.push(arr[i]) // 步骤 2小的放左边 else right.push(arr[i]) // 步骤 2大的放右边 } // 步骤 3递归排序 return [...quickSort(left), pivot, ...quickSort(right)] // 步骤 4合并 }原文档通过SortingAlgorithmDemo /组件提供排序过程可视化你可以生成数组后对比冒泡排序与快速排序的完整执行过程。3. 递归调用自己3.1 递归的原理递归是函数调用自身的编程技巧。两个关键要素基准情形base case什么时候停止递归递归步骤如何把问题分解成更小的子问题经典例子阶乘function factorial(n) { if (n 1) return 1 // 基准情形 return n * factorial(n - 1) // 递归步骤 }生活类比俄罗斯套娃。打开一个娃娃里面还有更小的娃娃直到最小的娃娃打不开为止。3.2 递归 vs 迭代特性递归迭代循环代码简洁度通常更简洁往往更复杂内存消耗高调用栈低性能略慢函数调用开销更快适用场景树遍历、分治算法简单重复任务逐项解读代码简洁度递归通常几行代码就能表达复杂逻辑如遍历树结构而循环往往需要更多变量和嵌套。内存消耗递归用调用栈保存每一层的信息像叠盘子每深入一层就多叠一个盘子循环没有这种开销。性能每次函数调用都有开销参数传递、栈操作等所以递归通常比循环略慢。适用场景递归擅长处理本身具有递归结构的问题文件树、DOM 树循环擅长简单重复操作遍历数组。⚠️ 递归的陷阱栈溢出递归太深调用栈空间耗尽。解决办法改用迭代使用尾递归优化部分语言支持限制递归深度。原文档通过RecursiveThinkingDemo /组件可视化递归的调用过程直观观察函数如何一层层调用自己。4. 贪心算法每一步选最优4.1 贪心思想贪心算法每一步都做出当前看起来最优的选择期望最终得到全局最优解。适用条件贪心选择性质局部最优能导向全局最优最优子结构问题的最优解包含子问题的最优解。经典例子硬币找零目标用最少数量的硬币凑出指定金额贪心策略每次都选面值最大的硬币结果67 元 50 10 5 1 15 枚。生活类比爬山时每次都选最陡的路往上爬。不一定能到达最高峰但通常能到相当不错的位置。4.2 ⚠️ 贪心并不总是最优反例硬币找零假设硬币面值为 [1, 3, 4]要凑出 6 元贪心法4 1 1 3 枚最优解3 3 2 枚。贪心算法在这里失败了教训贪心算法简单高效但并非总能得到最优解。使用之前必须证明问题满足贪心条件。比如上面这个反例用代码验证会更直观// 贪心策略每次都选最大面额 function greedyChange(coins, amount) { coins.sort((a, b) b - a) // 从大到小 let count 0 for (const c of coins) { while (amount c) { amount - c count } } return amount 0 ? count : Infinity } greedyChange([1, 3, 4], 6) // 得到 3但真实最优是 3 3 2 枚原文档通过GreedyThinkingDemo /组件让你尝试不同的硬币组合观察贪心策略的实际表现——当你试到 [1, 3, 4] 凑 6 时就能亲眼看到贪心的失败。5. 四大算法设计范式范式思想代表算法适合的问题分治法把问题分解成小问题快速排序、归并排序可分解的问题贪心法每次选最优最小生成树、哈夫曼编码具有贪心性质的问题动态规划记录子问题的解背包问题、最短路径有重叠子问题的问题回溯法试错走不通就回退八皇后、全排列搜索问题逐项解读分治法把大问题拆成小问题、分别解决再合并。就像打扫房间分成客厅、卧室、厨房分别打扫最后整体干净了。贪心法每次选当前最好的不考虑长远结果。就像吃饭时先吃最喜欢的菜未必是最优吃法但速度快。动态规划记忆中间结果避免重复计算。就像做笔记下次遇到同样的问题直接查答案不用重新推导。回溯法走不通就回退重试。就像走迷宫这条路不通就退回上一个岔路口换一条路。动态规划的一个直观示例——斐波那契数列正好演示记录子问题的解这一核心思想// 朴素递归大量重复计算重叠子问题 function fibNaive(n) { if (n 1) return n return fibNaive(n - 1) fibNaive(n - 2) // 时间复杂度 O(2ⁿ) } // 动态规划自底向上记录子问题结果 function fibDp(n) { if (n 1) return n const dp [0, 1] for (let i 2; i n; i) { dp[i] dp[i - 1] dp[i - 2] // 只算一次后面直接查表 } return dp[n] // 时间复杂度 O(n) }原文档通过AlgorithmParadigmDemo /组件对比不同设计范式的特点与适用场景。6. 复杂度分析入门选对量级原文档在章节总表中承诺了第 3 章 计算量分析并强调写代码前先估算数据规模与时间需求。这里把散落在各章中的复杂度知识汇总成一张速查表复杂度名称数据量翻倍后的表现典型例子O(1)常数级时间不变哈希表查找、数组按下标访问O(log n)对数级只增加固定次数二分搜索本章第 1 节O(n)线性级时间翻倍线性搜索、单次遍历O(n log n)线性对数级略超翻倍快速排序、归并排序本章第 2 节O(n²)平方级时间变为 4 倍冒泡排序、嵌套循环O(2ⁿ)指数级爆炸式增长朴素递归斐波那契估算三步法对应原文档计算量思维目标先问数据规模输入是 100、100 万还是 10 亿这直接决定你需要的复杂度量级再定算法量级O(n²) 算法在 100 万数据下意味着约 10¹² 次操作几乎是不可接受的最后权衡空间需要 O(n) 额外空间的算法如归并排序在内存受限的环境里可能不如原地排序如堆排序。7. 总结算法是解决问题的艺术用比喻把各种算法思想收束起来思想比喻核心要点二分搜索猜数字每次排除一半排序整理书架建立秩序递归俄罗斯套娃化大为小贪心法爬山选路局部最优核心启示算法的本质是效率与正确性的平衡。好算法能让程序效率产生数量级的提升但过度优化也可能带来不必要的复杂度先保证正确性再追求效率。理解算法思想比死记具体算法更重要分治把大问题拆成小问题贪心每次选最优动态规划记录子问题的解回溯试错走不通就回头。与 easy-vibe 课程体系的衔接本章属于 easy-vibe 计算机基础附录附录索引建议按以下路径继续深入学习下一站·数据结构算法离不开数据结构程序 数据结构 算法。紧接本章的 数据结构序论 会讲解数组、链表、哈希表、树、图以及它们与算法复杂度的关系——你在这里学到的二分搜索正是有序数组/平衡树的查询基础关联·编程语言编程语言 章节从语言层面解释递归、函数调用的底层机制可与本章递归一节互相印证落地·Vibe Coding 全栈Vibe Coding 全栈 展示如何把问题分解 → 复杂度估算 → 编写实现的算法思维应用到 AI 辅助的完整项目开发中语言对照若需中文对照可阅读 docs/zh-cn/appendix/1-computer-fundamentals/algorithm-thinking.md英文版见 docs/en/appendix/1-computer-fundamentals/algorithm-thinking.md其余语言版本位于 docs 下对应目录课程入口完整的附录导读见 docs/ja-jp/guide/introduction.md。参考资料《算法导论》系统学习算法的经典教材LeetCode通过刷题实战提升算法能力算法可视化工具直观理解算法的执行过程本仓库文档中的AlgorithmDemo /、SearchAlgorithmDemo /、SortingAlgorithmDemo /、RecursiveThinkingDemo /、GreedyThinkingDemo /、AlgorithmParadigmDemo /交互组件即承担类似可视化作用竞赛编程学习更高级的算法技巧。【免费下载链接】easy-vibe vibe coding 101The first course for AI-native product builders.项目地址: https://gitcode.com/GitHub_Trending/ea/easy-vibe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考