分治策略

爲何寫這個~
由於去年的一些變故,忘記了不少關於編程上的書面用語,因此找工做的過程就極其😅尷尬。。。算法

工做中常常用到一些問題,可是這些問題是由具備相同性質的小問題組合而成的,遇到這些問題時很天然的用了遞歸或循環的方式解決了問題。可是並不想不起來爲何用這些方法或者說方式處理這些問題的。編程

最後痛定思痛😂,仍是決定看書來一點一點找回書面上的東西,省得再有種野生的感受。。數組

廢話少說~ide

分治策略三個步驟

1.分解(divide),將問題劃分爲子問題,子問題和原問題的形式同樣,只是規模更小。直到分解爲足夠小的子問題,至於分解用什麼形式這些就很少說了。.net

2.解決(conquer),對足夠小的問題進行適合適當的求解。code

3.合併(combine),將子問題的解依次合併爲更大規模問題的解,直到合併結束。blog

例子:
排序算法,歸併排序
有一個數組,這個數組的元素排序爲亂序的。
數組爲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,繼續分解。get

      第二步,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;
}
相關文章
相關標籤/搜索