分而治之的核心思想是将一个复杂问题分解成多个较小、更容易处理的子问题,解决子问题后,再将子问题的解合并得到原问题的解!
什么是分治法?
分治法是一种算法设计策略。它遵循三步走战略:
- 分解(Divide): 将原问题分解成几个规模较小的、与原问题相似的子问题!
- 解决(Conquer): 若子问题规模足够小,则直接求解;否则递归地运用分治法求解子问题!
- 合并(Combine): 将子问题的解组合起来,得到原问题的解!
分治法的例子
让我们来看看一些生活中的例子和代码示例来说明分治法:
1. 二分查找: 在一个已排序的数组中查找特定元素。我们将数组分成两半,确定目标元素位于哪一半,然后递归地在该一半中重复这个过程,直到找到元素或数组为空!
-
例子: 查找数字 25 在数组 [2, 5, 11, 18, 25, 33, 41, 48] 中的索引!
先查中间(18), 25 > 18 -> 考虑右半边[25, 33, 41, 48] ; 再次在右半边查中间[33], 25 < 33 -> 调整思考的区间到其左半段[25, 33]; 这满足较小已按序子区域特点,所以直接发现25. 最后得到 索引!
2. 排序算法 (例如归并排序): 将一个尚未排好序的数组排好序。将它分成两个子数组,递归排序各子数组,再合并排好序的子数组!
- 例子: 排序数组 [3, 1, 4, 1, 5, 9, 2, 6]
通过重复地将数组分段,排好序然后再归并,得到最后的排好序列的排列!
3. 计算n的阶乘:递归拆分一直到达边界条件 1!:
程序例子(python):
python def factorial(n): if n <= 1: return 1 else: return n * factorial(n - 1)
print(factorial(5)) 输出 120
这个代码片段体现:先拆解出各个比较小的算式单元 n*(n -1);然后每个环节返回结果,叠加成n.
4. 快速排序 :这是一种比较常见的应用;跟归纳排例具有类似思维;
挑选基准点-->拆分成独立部分 划分 循环操作后-->最后一步合并不同独立区域组成终极单元-- >算法完成
分治法的适用条件
并非所有问题都适合用分治法解决。分治法最适合的问题具有以下特点:
- 问题可以分解成较小子问题。
- 子问题与原问题具有类似结构,可以用递归求解。
- 子问题的解组合起来得到原问题的解。
分治法的优劣
优点: 便于模块化程序编写,处理大型复杂信息更加得心应手.;针对部分问题优化性能有突出优势;
缺陷也难以避免: 分割太多步骤的计算环节对CPU占用相对较高一些;(需要根据情境具体调整应用范围。)部分复杂问题虽然能够分解但是解决后合并答案 阶段的计算量较大;甚至可能导致组合难度反而超出单个单元问题自身
总之, 对很多常见的信息操作,它都发挥巨大作用!