递归分治策略

  在前面的随笔中其实谈到了一些递归分治的算法,也以为自己写上去了,今天在看到没有写。下面就来补上。

  递归分治是算法中比较重要的思想。在之前也聊到了递归和递推的区别。递归这里就不再详细讲述了。下面讲一讲分治。分治其实很简单,就是将一个比较大的问题分解为很多的小问题,解决小问题的最优解比解决大问题的最优解要简单的多,很多的小问题的最优解就组成了大问题的最优解。从这里也可以发现,递归和分治在一起用的话会比较好,同时也是容易想到的。

  下面讲一讲递归的一些我会的东西,递归就是间接和直接调用自身的算法。比如斐波那契数列就是用递归比较简单解决的问题之一。递归有三个要素,递归主体,递归边界,递归参数。这三个要素组成了递归。先讲一讲递归的主体,递归的主体算法就是递归的主体,这一部分是比较重要的,因为递归的大部分操作都在这里实现。递归边界就是递归的尽头,因为任何一个算法都要在有限的时间内得出结果,否则就是失败的,递归的边界就给递归提供了一个结束的具体条件。递归的参数是每次递归发生变化的数值,有时为了输入的方便,递归的参数会有一部分参数没有发生变化,这也是可以的。

  纸上谈兵终究学不会,下面就来具体就问题来详细探讨一下。

  先讲一个简单的,容易想的。“最长公共子序列”问题,最长公共子序列问题可能大家用动态规划做的比较多,因为用动态规划比递归要简单的多。但是最长公共子序列也可以用递归来做。下面就来讲一讲具体的实现,最长公共子序列问题就是在两串字符串中找出来两个字符串都具有的子序列(子序列可以间断,但是顺序不可以乱)。问题了解了,谈谈思路吧,分治的思想就是将问题分为小问题,我们将问题分解为一个字符的比较,这个就简单了。同时也可以用递归来将剩余的问题交给下一个自身算法来解决。这样递归的主体就是解决一个字符的比较。但是下面遇到了一个问题,当前比较的字符一样时还可以往下面递归,但是不一样时该怎么递归呢?我们可以将A,B比作两个字符串,i表示当前比较的字符,i-1就是下一个字符的位置。这样当Ai==Bi时,递归就是Ai-1和Bi-1的比较。当Ai和Bi不一样时,就可以分为Ai与Bi-1和Ai--1与Bi的比较,这样,还是递归到了下一个子问题。比较两者的大小,选出大的就可以了。

  递归的主体解决了,下面解决递归的边界。递归的边界可能大家想到了当i==0时,就结束了,这个比较好想到,但是其他的问题递归的边界可能就不是很好想了。递归的参数就呼之欲出了,两个字符串的比较位置就是参数(也可以将字符串比较一次直接删除比较的元素),这里要注意的就是递归常用的一个方法,试探与回溯,因为算法不可能直接求出来最优解,需要算法不停的试探下一个结果是对还是错,同时还要回到算法开始的位置。(本题可能并不需要这种方法,因为并没有对字符串做出更改)。

  上面就是最长公共子序列的递归算法的大致思路,这里因为一些原因(懒),这里就不在列出代码。上面可能就是一个大致的思路,具体的细节可能还会有一些不一样。但是大致一致。下面就练习一个简单的递归思路。

  求出一个数组所有的元素和,这个问题很多人估计一个for循环就可以完成了,但是我们是用递归的思想来实现。下面来说一说思路。

  先想一下递归的主体,我们可以计算当前数组位置的一个元素的和,然后将剩下的交给后面的递归算法来做。主体完成,递归的边界也就容易想到,当数组中的所有元素递归一遍后就是递归结束的边界。递归的参数前面也是很简单,当前累加的元素的位置就是参数,这里为了方便也将数组作为参数传了进来。

  算法的实现我用了一个更加复杂的方式(顺便练一练二分),就是将递归的算法交给了两部分,只是计算了数组的中间位置(或者中间位置都没有计算)。下面就粘贴具体代码:

public class demo5
{
	public static int f(int a[],int end)
	{
		if(end<0)
		{
			return 0;
		}
		return f(a,end-1)+a[end];

	}
	public static int f(int a[],int min,int max)
	{
		int mid=(max+min)/2;
		if(mid==max){
			return a[max];
		}
		return f(a,min,mid)+f(a,mid+1,max);

	}
	public static void main(String args[])
	{
		int a[]={2,3,4,5,6,7,8,10};
		int i=f(a,0,7);
		System.out.println(i);
	}

}

  代码没有什么难点,看看就明白了

原文地址:https://www.cnblogs.com/yanyu01/p/8783496.html

时间: 2024-11-01 15:58:10

递归分治策略的相关文章

分治策略结合递归思想求最大子序列和

我的主力博客:半亩方塘 对于 <数据结构与算法分析--C语言描述> 一书第 20 页所描述的算法 3,相信会有很多人表示不怎么理解,下面我由具体问题的求解过程出发,谈谈我自己的理解: 首先,什么是分治法呢?所谓 分治法,就是 将一个问题的求解过程分解为两个大小相等的子问题进行求解,如果分解后的子问题本身也可以分解的话,则将这个分解的过程进行下去,直至最后得到的子问题不能再分解为止,最后将子问题的解逐步合并并可能做一些少量的附加工作,得到最后整个问题的解.在求解原来整个问题的算法思想,与求解每一

递归与分治策略(一)---算法设计与分析

递归与分治策略(一) 简而言之,递归就是自己调用自己. 递归算法:直接或者间接地调用自身的算法. 递归函数:用函数自身给出定义的函数. 注意:每个递归函数都必须有非递归定义的初始值,以确保递归函数完成计算. 下面通过两个例子来介绍递归的特点 例1 阶乘函数 阶乘函数递归地定义为: n!=1   (n=0) 或者 n!=n(n-1)!  (n>0) 下面用一段简单的Java代码实现 这里是递归实现: public static int facterial(int n) { if (n == 0)

计算机算法设计与分析之递归与分治策略——二分搜索技术

递归与分治策略 二分搜索技术 我们所熟知的二分搜索算法是运用分治策略的典型例子,针对这个算法,先给出一个简单的案例. 目的:给定已排好序的n个元素a[0:n-1],现要在这n个元素中找出一特定的元素x. 我们首先想到的最简单的是用顺序搜索方法,逐个比较a[0:n-1]中元素,直至找出元素x或搜索遍整个数组后确定x不在其中.这个方法没有很好地利用n个元素已排好序的这个条件,因此在最坏的情况下,顺序搜索方法需要O(n)次比较. 而二分搜索方法充分利用了元素间的次序关系,采用分治策略,可在最坏情况下用

算法分析之递归与分治策略

递归与分治策略 直接或间接地调用自身的算法称为递归算法.用函数自身给出定义的函数称为递归函数. 在计算机算法设计与分析中,使用递归技术往往使函数的定义和算法的描述简洁且易于理解. 例1 阶乘函数 可递归地定义为:其中:n=0 时,n!=1为边界条件n>0 时,n!=n(n-1)!为递归方程边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果. 例2 Fibonacci数列无穷数列1,1,2,3,5,8,13,21,34,55,…,被称为Fibonacc

五大常见算法策略——递归与分治策略

摘要:递归与分治策略是五大常见算法策略之一,分治策略的思想就是分而治之,即先将一个规模较大的大问题分解成若干个规模较小的小问题,再对这些小问题进行解决,得到的解,在将其组合起来得到最终的解.而分治与递归很多情况下都是一起结合使用的,能发挥出奇效(1+1>2),这篇文章我们将先从递归说起,再逐渐向分治过渡,主要讲解方式是通过9个例题来说明问题的,问题都是根据难度由简到难,由浅入深,对递归与分治能有个大概的了解雏形,当然最重要还是要做大量练习才能掌握. 1.递归 我们第一次接触递归一般都是在初学C语

分治策略 - 最大子序列问题

自开始学习算法起,我感觉就是跪着把<算法导论>的代码看一遍.理解一遍然后敲一遍...说实话自己来写并且要求时间复杂度达到要求,我肯定是不能做到的,但我想前辈们辛苦积累的研究成果贡献出来也是为了让后人少走一些弯路,所以我的作用就是把前辈们的成果学习之后加以理解,然后积累经验,领悟到他们解决问题时的思路和灵感.还有就是把个人理解后的知识存储在不会忘记的地方作为复习备用... 当然什么是写博客呢,我个人认为是把所学的知识加上自己的理解然后用较为通俗的语言来解释一遍,至少这样才有可能把学到的东西变为自

分治策略

 分治策略分为三步: 分解原问题:将原问题分解为一些子问题,子问题形式与原问题一样,只是规模更小. 解决子问题:递归的求解出子问题.如果子问题规模足够小,则停止递归,直接求解. 合并子问题:将子问题的解合并为原问题的解 主方法公式:T(n)=aT(n/b)+f(n);它刻画了这样一个分治算法:生成a个子问题,每个子问题的规模是原问题的1/b,分解合并子问题时间为f(n);

第四章 分治策略——最大子数组问题

最大子数组问题 方法一:暴力求解方法 我们可以很容易地设计出一个暴力方法来求解本问题:简单地尝试没对可能的子数组,共有O(n2)种 #include<iostream> using namespace std; #define INT_MIN 0x80000000 int main() { int arr[10]={9,8,-3,-5,7,-39,79,-37,8,9}; int i,j; int sum=0,maxsum=INT_MIN; int imax; for(i=0;i<10;

【经典算法】分治策略

一.什么是分治 有很多算法是递归的:为了解决一个给定的问题,算法要一次或多次递归调用其自身来解决的子问题.这些算法通常采用分治策略:将原问题划分为n个规模较小而结构与原问题相似的子问题:递归地解决这些子问题,然后再合并其结果,就得到原问题的解. 二.分治算法的三个步骤 分治模式在每一层递归上都有三个步骤: 分解(Divide)步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小. 解决(Conquer)步骤递归地求解出子问题.如果子问题规模足够小,则停止递归,直接求解. 合并(Co