引入:从递归到搜索
上一篇我们学习了递归:函数自己调用自己,把大问题拆成小问题。递归非常适合解决一类叫做“搜索”的问题。
想象你在一个迷宫里找出口。你的策略可能是:随便选一条路往前走,能走就一直走;遇到死胡同就退回到上一个岔路口,换另一条路。这种“一条路走到黑,走不通再回头”的策略,就是深度优先搜索,简称 DFS(Depth-First Search)。
DFS 是算法学习中的里程碑。掌握了它,你就可以解决走迷宫、全排列、子集、连通块等一大批经典问题。
上一篇我们学习了递归:函数自己调用自己,把大问题拆成小问题。递归非常适合解决一类叫做“搜索”的问题。
想象你在一个迷宫里找出口。你的策略可能是:随便选一条路往前走,能走就一直走;遇到死胡同就退回到上一个岔路口,换另一条路。这种“一条路走到黑,走不通再回头”的策略,就是深度优先搜索,简称 DFS(Depth-First Search)。
DFS 是算法学习中的里程碑。掌握了它,你就可以解决走迷宫、全排列、子集、连通块等一大批经典问题。
上一篇我们学了 DFS:遇到岔路先挑一条走到底,走不通再回头。这种策略很直观,但在某些问题里不是最优的。
比如你想知道从起点到终点最少要走多少步。如果用 DFS,你可能先沿着一条很长的死路走到底,才发现不是最优解;而更好的做法是:先扩展起点周围所有一步能到的地方,再扩展两步能到的地方,以此类推。这就是广度优先搜索,简称 BFS(Breadth-First Search)。
BFS 的思想就像往水面扔一颗石子,波纹一圈一圈向外扩散。
到目前为止,你已经能熟练操作数组、链表、栈和队列了。但很多时候,光把数据存起来还不够,你还需要让它们有序。
比如成绩表想按分数从高到低排、字典里的单词要按字母顺序排、商品列表要按价格排序。这些场景都离不开排序算法。排序也是很多更复杂算法的基础:二分查找要求数组有序,很多贪心、分治算法也要先排序。
这一篇我会带你实现三种最基础、最经典的排序算法:冒泡排序、选择排序和插入排序。它们思路简单,但已经足以帮你理解“算法复杂度”这个核心概念。
几乎每一个程序都离不开放东西和找东西:从用户列表里找某个账号、从字典里查一个单词、从日志里定位一条记录。上一篇我们学会了排序,今天就来学习如何利用有序性,把查找速度大幅提升。
查找算法有很多种,我们从最简单的顺序查找开始,再过渡到效率更高的二分查找。
left、right、mid 的边界处理。在学习链表、排序和搜索之前,需要先有一把比较算法的尺子。复杂度不是给代码贴一个神秘公式,而是描述:输入规模变大时,工作量怎样增长。
同一段程序的耗时会受到 CPU、编译器、优化级别、系统负载和测试数据影响。秒数适合做最终测量,却不适合作为第一层通用分析。
复杂度忽略机器常数,关注增长趋势。例如处理 n 个元素:
O(1);O(n);O(n²);O(log n)。