• 递归与分治[2019.5.25]


    1、 $sqrt { m{n}} $段合并排序算法:

      将数组a[0,n-1]划分为$sqrt { m{n}} $个子数组,每个子数组有O($sqrt { m{n}} $)个元素。然后递归地对分割后的子数组进行排序,最后将所得到的$leftlfloor {sqrt { m{n}} } ight floor $个排好序的子数组合并排序。

      分治算法基本思想

      将数组分为$sqrt { m{n}} $个子问题,递归的结束条件为根号子问题规模≤1,根据根号下内容不同,分为1、2、3),对于问题排序,然后归并。

       Code:

    #include <bits/stdc++.h>
    using namespace std;
    void sort_2_3(int* arr, int p, int q){
        int num = q - p + 1;
        if(num == 2){
            cout<<"sort_2_3 2:"<<arr[p]<<","<<arr[p+1]<<endl;
            if(arr[p] > arr[p+1]){
                int tmp = arr[p];
                arr[p] = arr[p+1];
                arr[p+1] = tmp;
            }
            cout<<"sort_2_3 2:"<<arr[p]<<","<<arr[p+1]<<endl;
        }
        else if(num == 3){
            cout<<"sort_2_3 3:"<<arr[p]<<","<<arr[p+1]<<","<<arr[p+2]<<endl;
            int Min = arr[p];
            int Max = arr[p];
            int min_i = 0;
            int max_i = 0;
            for(int index=0; index<3; index++){
                if(arr[p + index] < Min){
                    Min = arr[p + index];
                    min_i = index;
                }else if(arr[p + index] > Max){
                    Max = arr[p + index];
                    max_i = index;
                }
            }
            int Mid = arr[ p + 3 - min_i - max_i ];
            arr[p] = Min;
            arr[p + 1] = Mid;
            arr[p + 2] = Max;
            cout<<"sort_2_3 3:"<<arr[p]<<","<<arr[p+1]<<","<<arr[p+2]<<endl;
        }
    }
    
    void Merge(int*arr, int p, int q){
        cout<<"merge:"<<p<<","<<q<<endl;
        for(int i=p;i<=q;i++){
            cout<<arr[i]<<" ";
        }
        cout<<endl;
        int n = q - p + 1;
        int num = int(sqrt(n));
        //开辟暂存空间
        int i=0;
        vector<vector<int> > tmps (num);
        for(; i< num- 1; i++){
            tmps[i].resize(num + 1);
        }
        tmps[i].resize(n - i*num + 1);
    
        //初始化数据
        for(i=0; i < num - 1; i++){
            int j=0;
            for(; j < num; j++){
                tmps[i][j] = arr[p + i*num + j];
            }
            tmps[i][j] = INT_MAX;
        }
        int in = 0;
        for(; in < n - i * num; in++)
            tmps[i][in] = arr[p + i*num + in];
        tmps[i][in] = INT_MAX;
        cout<<"初始化数据:"<<endl;
        for(int i=0; i<num;i++){
            for(int j=0;j<tmps[i].size();j++){
                cout<<tmps[i][j]<<" ";
            }
            cout<<endl;
        }
        cout<<"初始化数据."<<endl;
        //每行标记
        int poses[num];
        for(int i=0; i<num ;i++){
            poses[i]=0;
        }
        //比较
        int Min = tmps[0][0];
        int index_row = 0;
        for(i=p; i<=q; i++){
            for(int j=0; j<num; j++){
                if(tmps[j][poses[j]] < Min){
                    Min = tmps[j][poses[j]];
                    index_row = j;
                }
            }
            arr[i] = tmps[index_row][poses[index_row]];
            Min = tmps[index_row][poses[index_row] + 1];
            poses[index_row]++;
        }
        for(int i=p;i<=q;i++){
            cout<<arr[i]<<" ";
        }
        cout<<endl;
    }
    void sqrt_n_sort(int* arr, int p, int q){
        cout<<"deviation"<<endl;
        int n = q -p + 1;
        int num = int(sqrt(n));
        if(num > 1){
            int i=0;
            for(;i < num -1 ; i++){
                cout<<p + num*i<<","<<p + num*(i+1) - 1<<endl;
                sqrt_n_sort(arr, p + num*i, p + num*(i+1) - 1 );
            }
            cout<<p + num*i<<","<<q<<endl;
            sqrt_n_sort(arr, p + num*i, q);
            Merge(arr, p, q);
        }else{
            sort_2_3(arr,p,q);
        }
    }
    
    int main(){
        int arr[10] = {1,2,3,4,5,6,7,8,9,10};
        sqrt_n_sort(&arr[0], 0, 9);
    
        for(int i=0; i<10; i++){
            cout<<arr[i]<<" ";
        }
        return 0;
    }

     

     

    2、 用分治法设计一个算法,在数组A中寻找最大元素和最小元素

      将数组a[0,n-1]划分为$sqrt { m{n}} $个子数组,每个子数组有O($sqrt { m{n}} $)个元素。然后递归地对分割后的子数组进行排序,最后将所得到的$leftlfloor {sqrt { m{n}} } ight floor $个排好序的子数组合并排序。排序后即可得到max与min。

    #include <bits/stdc++.h>
    using namespace std;
    void sort_2_3(int* arr, int p, int q, int* arr_min_max){
        int num = q - p + 1;
        int len = 0;
        if(num == 2){
            len = 2;
        }else if(num == 3){
            len = 3;
        }
        for(int i=p; i < p + len; i++){
            if(arr[i] < arr_min_max[0]){
                arr_min_max[0] = arr[i];
            }
            if(arr[i] > arr_min_max[1]){
                arr_min_max[1] = arr[i];
            }
        }
    }
    
    void sqrt_n_sort(int* arr, int p, int q, int* arr_min_max){
        cout<<"deviation"<<endl;
        int n = q -p + 1;
        int num = int(sqrt(n));
        if(num > 1){
            int i=0;
            for(;i < num -1 ; i++){
                cout<<p + num*i<<","<<p + num*(i+1) - 1<<endl;
                sqrt_n_sort(arr, p + num*i, p + num*(i+1) - 1, arr_min_max);
            }
            cout<<p + num*i<<","<<q<<endl;
            sqrt_n_sort(arr, p + num*i, q, arr_min_max);
        }else{
            sort_2_3(arr,p,q,arr_min_max);
        }
    }
    
    int main(){
        int arr[10] = {1,2,3,4,5,6,7,8,9,10};
        int arr_min_max[2] = {INT_MAX,INT_MIN};
        sqrt_n_sort(&arr[0], 0, 9, &arr_min_max[0]);
    
        cout<<"min:"<<arr_min_max[0]<<" max:"<<arr_min_max[1]<<endl;
        return 0;
    }
  • 相关阅读:
    女程序员这么少是因为怕秃头?如果你这样想,那就错了...
    使用简单的c#示例的坚实的架构原则
    第1部分设计模式FAQ(培训)
    为什么微软部分类和Java不?
    现实世界四部分类和部分方法的使用
    回到基础:n层ASP的异常管理设计指南。网络应用
    学习c#(第9天):理解c#中的事件(一种见解)
    EventBroker:同步和异步通知组件,松散耦合的事件处理
    潜水在OOP(第一天):多态和继承(早期绑定/编译时多态)
    学习c#(第8天):c#中的索引器(一种实用方法)
  • 原文地址:https://www.cnblogs.com/cruelty_angel/p/11021542.html
Copyright © 2020-2023  润新知