1介绍
分治算法已经是本人所写的常用算法系列的第三个了,可能只会写这一节,对比动态规划与贪心算法我们来认识一下分治算法。从思路上来看:
(1)动态规划:多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。每一个阶段的最优解是基于前一个阶段的最优解。
(2)贪心算法:选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。不是对所有问题都能得到整体最优解。
(3)分治算法:将一个大规模的问题分解成n个容易解决的小问题,当小问题被解决时,最终的问题也被解决了。
乍一看,似乎区别不大。
从代码结构上来看(不绝对):
(1) 动态规划:通常为两层for循环嵌套;
(2) 贪心算法:通常先进行排序,后进行选择;
(3) 分治算法:通常为递归;
2归并排序
2.1问题
问题:使用归并排序以下数字:8,7,4,2,2,1,19,23,5,3
2.2解析
按照分治算法的思想,题中数组Array有10个数字,不太方便操作,应该将其分解为若干个容易解决的子问题。假设现在排序的是包含1个数字的数组Array,是不是就非常容易了(一个数字都不用排序)。现将数组Array分解为10个数组,每个数组只含有1个数字,这就是归并排序中“归”的过程。
数组只含有1个数字,可见该数组已经有序了。然后将两个有序的数组合并起来,当然合并的时候也要确保合并之后的数组也是有序的。这就是归并排序中“并”的过程。
归并排序的处理过程:
(1)“归”:拆分为只含有一个数字的数组;
void SplitSort(int first,int last,int a[],int temp[]){
if (last>first){
int mid = (first + last) / 2;
SplitSort(first,mid,a,temp);
SplitSort(mid+1,last,a,temp);
MergeSort(first,last,mid,a,temp);
}
}
(2)“并”:将两个有序的数组合并成一个有序的数组;
void MergeSort(int first,int last,int mid,int a[],int temp[]){
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
本题完整源代码:
#include<iostre