工作中经常用到一些问题,但是这些问题是由具有相同性质的小问题组合而成的,遇到这些问题时很自然的用了递归或循环的方式解决了问题。但是并不想不起来为什么用这些方法或者说方式处理这些问题的。
废话少说~
分治策略三个步骤
1.分解(divide),将问题划分为子问题,子问题和原问题的形式一样,只是规模更小。直到分解为足够小的子问题,至于分解用什么形式这些就不多说了。
2.解决(conquer),对足够小的问题进行适合适当的求解。
3.合并(combine),将子问题的解依次合并为更大规模问题的解,直到合并结束。
例子:排序算法,归并排序
有一个数组,这个数组的元素排序为乱序的。
数组为O [13,2,4,3,14],不做更短或更长的原因,更短体现不了这个思想,更长演示过程会麻烦。
按照流程
1.分解,将数组进行分解,分解策略为取半,即数组长度 除 2 (向上取整)分为更小规模的数组
第一步,O [13,2,4,3,14]
分解分为 A [13, 2, 4]
和 B [3,14]
两个数组。
A B 数组长度均大于1,继续分解
此时结果为A[13, 2, 4]
、B [3, 14]
A
,B
数组长度大于1,继续分解。
第二步,A[13, 2, 4]
分解为 A1 [13, 2]
、 A2 [4]
,B [3,14]
分解为B1 [3]
、B2 [14]
。
此时结果为A1 [13, 2]
、 A2 [4]
、 B1 [3]
、B2 [14]
A1
数组长度大于1,继续分解。
第三步,A1 [13, 2]
分解为A11 [13]
、 A12 [2]
。
此时结果为A11[13]
、A12 [2]
、A2[4]
、B1[3]
、B2 [4]
长度都等于1,分解停止
2.求解,因为只是排序,对结果不需要进行进一步的操作
3.合并,对分解的数组进行合并,从最下级开始
对最下级的A11[13]
,A12[2]
进行合并,得到A1[2, 13]
此时最下级不存在,上一级进行合并
对A1
,A2
进行合并,得到A[2, 4, 13]
,对B1
,B2
进行合并,得到B[3, 14]
对上一级进行合并
对A B 进行合并,得到A[2, 3, 4 , 13, 14]
此时无上一级,合并结束,返回A
C语言代码如下,或参考基础排序算法:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
void merge(int arr[],int left,int mid,int right){
int *tmp_arr;
int tmp_num = right - left + 1;
tmp_arr = (int*)malloc(sizeof(int)*tmp_num);
int i=left,j=mid+1,k=0;
while(i<=mid && j<=right){
if(arr[i] < arr[j]){
tmp_arr[k++] = arr[i++];
}else{
tmp_arr[k++] = arr[j++];
}
}
while(i<=mid){
tmp_arr[k++] = arr[i++];
}
while(j<=right){
tmp_arr[k++] = arr[j++];
}
printf("sort after... left %d mid %d right %d\n",left,mid,right);
for(i=left,j=0;i<=right;i++,j++){
arr[i] = tmp_arr[j];
printf("%d\n", arr[i]);
}
free(tmp_arr);
}
void sort_merge(int arr[],int left,int right){
if(left < right){
int mid;
mid = floor((left+right)/2);
printf("sort start... left %d mid %d right %d\n",left,mid,right);
for(int i=left;i<=right;i++){
printf("%d\n", arr[i]);
}
sort_merge(arr,left,mid);
sort_merge(arr,mid+1,right);
merge(arr,left,mid,right);
}
}
int main(){
int arr[5] = [13,2,4,3,14];
int length = sizeof(arr)/sizeof(arr[0]);
printf("start: \n");
for(int k = 0 ;k<length;k++){
printf("%d\n", arr[k]);
}
sort_merge(arr,0,length - 1);
printf("result:\n");
for(int i = 0 ;i<length;i++){
printf("%d\n", arr[i]);
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。