算法—分治法

1 分治法的设计思想

分而治之算法的设计思想是,将一个难以解决的大问题,分割成几个规模较小的相似问题,以便于各个击破,分而治之。

分治法算法思想如下:
(1) 将一个问题划分为同一类型的若干子问题,子问题最好规模相同。
(2) 对这些子问题求解(一般使用递归方法,但在问题规模足够小时,有时也会利用另一个算法)。
(3) 有必要的话,合并这些子问题的解,以得到原始问题的答案。
当子问题足够大时,需要递归求解时,我们称之为递归情况(Recursive Case)。当子问题变得足够小,不再需要递归时,表示递归已经“触底”,进入了基本情况(Base Case)。
 

2 适合分治法的策略的问题

分治法所能解决的问题一般具有以下几个特征:

  • 该问题的规模缩小到一定的程度就可以容易地解决
  • 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
  • 利用该问题分解出的子问题的解可以合并为该问题的解;
  • 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。

第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;

第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;

第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。

第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。

3 实际案例

a)归并排序

public class Mergesort {  
	public static void merge(int[]a,int low,int mid,int high){
		//对两组已经排序的数组进行合并   
		int[]b=new int[high-low+1];   
		int s=low;   
		int t=mid+1;   
		int k=0;   
		while(s<=mid&&t<=high){
		    if(a[s]<=a[t])     
		       b[k++]=a[s++];    
		     else     
			b[k++]=a[t++];   
		}   
		
		while(s<=mid)    
			b[k++]=a[s++];   
			
		while(t<=high)       
			b[k++]=a[t++];   
			
		for(int i=0;i<b.length;i++){
		    a[low+i]=b[i];   
		}  
	}  
	
	public static void mergesort(int a[],int low,int high){
		//对数组进行递归排序   
		if(low<high){
		    mergesort(a,low,(low+high)/2);    
		    mergesort(a,(low+high)/2+1,high);    
		    merge(a,low,(high+low)/2,high);   
		}  
	}  
	
	public static void main(String[]args){
	   int[]a={49,38,65,92,76,13,27};   
	   System.out.println("排序前数组为:");   
	   for(int i=0;i<a.length;i++){    
		System.out.print(a[i]+" "); 
	   }   
	   
	   mergesort(a,0,a.length-1);   
	   System.out.println("\n排序后数组为:");   
	   for(int i=0;i<a.length;i++){    
		System.out.print(a[i]+" ");
	   }   
	} 
	
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值