算法的设计之分治方法

算法的设计

关键在于记住其思想、步骤和使用条件

1、什么是分治法

     当求解的问题较复杂或规模较大时,不能立刻得到原问题的解,但这些问题本身具有这样的特点,它可以分解为若干个与原问题性质相类似的子问题,

而这些子问题较简单可方便得到它们的解,因此通过合并这些子问题的解就可得到原问题的解。

2、应用分治法的三个基本步骤

①分解问题(divide):把原问题分解为若干个与原问题性质相类似的子问题

②求解子问题(conquer):不断分解子问题直到可方便求出子问题的解为止

③合并子问题的解(combine):合并子问题的解得到原问题的解

3. 分治法适用条件

①原问题可以分解为若干个与原问题性质相类似的子问题

②问题的规模缩小到一定程度后可方便求出解

③子问题的解可以合并得到原问题的解

④分解出的各个子问题应相互独立,即不包含重叠子问题

分治算法举例:

归并排序

思想:如果能把原待排序的数组分解成若干个待排序的子数组,而这些子数组可以方便地排好序,并且通过合并这些子数组的解将能得到原问题的解,则整个数组将排好序。

 

应用分治法解题的三个基本步骤为:

①divide:把具有n个元素的数组分解为二个n/2大小的子数组

②conquer:递归地分解子数组,直到子数组只包含一个元素为止

③combine:二二合并已排好序的子数组使之成为一个新的排好序的子数组,重复这样二二合并的过程直到得到原问题的解

 按照步骤实现的方法:

public void mergeSort(int []A,int p,int r)
{
        if(p<r)
    {
         int q=(p+r)/2;//相当于取下整
         mergeSort(A,p,q);
         mergeSort(A,p+1,r);
         merge(A,p,q,r);
    }         
}    

 (因为是递归,所以在每一级的变量都有其每一级的特定值)

 注释:1、首先q=(p+r)/2;是满足步骤①

   2、mergeSort(A,p,q)、mergeSort(A,q+1,r)和p<r是满足②

   3、merge(A,p,q,r)满足了步骤③combine

 

merge代码:

public static void merge(int[]A,int p,int q,int r){
        int n1=q-p+1;//为上半段长度(由于是取下整)
        int n2=r-q;//为下半段长度        
        int[]L=new int[n1+1];
        int[]R=new int[n2+1];
        
        for(int i=0;i<n1;++i){
            L[i]=A[p+i];
        }
        for(int i=0;i<n2;++i){
            R[i]=A[q+i+1];
        }
        L[n1]=65535;
        R[n2]=65535;
        int i=0,j=0;
        for(int k=p;k<=r;++k){//k是代表从数组A,所以要<=r
            if(L[i]<=R[j]){   //依次比较L和R,之后存储到A中
                A[k]=L[i];
                i=i+1;
            }else{
                A[k]=R[j];
                ++j;
            }
            //System.out.print("p="+p+"   k="+k+"   i="+i+"   j="+j);
            //System.out.println("   A["+k+"]="+A[k]+"   r="+r);
        }    
    }

 L[n1]、R[n2],是标志位,标志着到达了数组的末尾。

 

posted @ 2017-02-23 18:41  mslog  阅读(690)  评论(0编辑  收藏  举报