分治算法

来源:互联网 发布:系统时间锁定软件 编辑:程序博客网 时间:2024/06/01 09:25

如下有关分治法的问题:

金块问题:
老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。并对自己的程序进行复杂性分析。


首先分析一下问题:
对于一般思路:通过一个函数Max进行n-1次比较来找到最重的金块,然后再从余下的n-2个金块中用同样的方法Min函数找到最轻的金块,这样,比较的总次数为2n-3。
对于 分治法:(分治法是将问题划分为若干个子问题,然后通过求解子问题的解来获得原问题的解)

  1. 先考虑n≤2的情况
    ①当n=1时,即只有一块金子,此时无需进行比较
    ②当n=2时,此时只需比较一次就可以判断出最重和最轻的金块

  2. 对于n>2的情况
    第一步,将金子平均分成两份A,B
    第二步,分别在A,B中找到最重和最轻的金块
    第三步,再次比较A中最重的金子和B中最重的金子,A中最轻的金子和B中最轻的金块

时间复杂度:

  • 若n=0
    T(n)=0
  • 若n=1
    T(n)=1
  • 若n>2
    T(n)=2T(n/2)+2
    通过Master定理可得为O(n)

代码的总体设计逻辑就是将n个金块分成等量的两份A,B,然后再将A分成等量的两份(若A中金块的数量n1>2),然后再次等量分,通过一次次的划分,找到符合n=1或n=2的情况,然后直接进行比较,总体来说就是不断的递归

代码:

#include<stdio.h> //比较重量大小的函数int min(int x,int y){        if(x<y)             return x;      else             return y; }int max(int x,int y){        if(x>y)              return x;      else             return y; }int Find_min(int A[],int left,int right)  //这里是寻找最轻的金块的函数{       int la,ma,ra;    if(left==right)    //对于n=1的情况    {        int min;        min=A[right];        return min;    }    if(right-left==1)    //对于n=2的情况    {        la=A[left];        ra=A[right];        return(min(la,ra));    }    if(right-left>1)   //对于n>2的情况    {        ma=(left+right)/2;              la=Find_min(A,left,ma);         ra=Find_min(A,ma,right);        return(min(la,ra));         }       }   int Find_max(int A[],int left,int right)  //寻找最重金块的函数{       int la,ma,ra;       if(left==right)    {            int max;            max=A[right];            return max;       }        if(right-left==1)        {            la=A[left];            ra=A[right];            return(max(la,ra));         }          if(right-left>1)    {               ma=(left+right)/2;              la=Find_max(A,left,ma);              ra=Find_max(A,ma,right);              return(max(la,ra));         }       }   int main(){        int A[100];      int n;         int min;    int max;       printf("请输入金块数目:");       scanf("%d",&n);       printf("请输入各金块的重量:");       for(int i=0;i<n;i++)           scanf("%d",&A[i]);        printf("最重的金块:");       max=Find_max(A,0,n-1);        printf("%d",max);          printf("\n");       printf("最轻的金块:");       min=Find_min(A,0,n-1);         printf("%d",min);     printf("\n");     return 0;}

这里写图片描述

原创粉丝点击