第三章 分治算法
1. 基本思想
对于一个规模为n的问题,若该问题可以容易地解决(比如n的规模比较小),则直接解决,否则将其分解为k个规模比较小的子问题,这些子问题相互独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并,得到原问题的解。这种算法设计策略叫做分治法。
2. 解题步骤
(1)划分(divide):将原问题分解为若干规模较小、互相独立、与原问题形式相同的子问题。
(2)解决(conquer):若子问题规模较小,则直接求解;否则递归求解各子问题。
(3)合并(combine):将各子问题的解合并为原问题的解。
3. 适用条件
4. 经典例题
(1)二分搜索
(2)合并排序
基本思想:将待排序元素分成大致相同的2个子集合,分别对2个子集合进行排序,最终将排序好的子集合合并成为所要求的排好的集合。
void MergeSort(Type a[], int left, int right)
{
if (left<right) {//至少有2个元素
int i=(left+right)/2; //取中点
mergeSort(a, left, i);
mergeSort(a, i+1, right);
merge(a, b, left, i, right); //合并到数组b
copy(a, b, left, right); //复制回数组a
}
}
复杂度分析:
T(n)=O(nlogn)渐进意义下的最优算法。
最坏时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
辅助空间:O(n)
(3)快速排序
基本思想
算法
时间复杂度
算法优化
- 更好的划分元素选择方法:三平均分区。
- 当子数组足够小时改用简单的排序方法。
- 将分区为分为三块而不是原来的两块:一块是下与中轴值的所有元素,一块是等于中轴值的所有元素,另一块是大于中轴值的所有元素。