工作中经常用到一些问题,但是这些问题是由具有相同性质的小问题组合而成的,遇到这些问题时很自然的用了递归或循环的方式解决了问题。但是并不想不起来为什么用这些方法或者说方式处理这些问题的。

废话少说~

分治策略三个步骤

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;
}

冰茶么么哒
31 声望2 粉丝