zoukankan      html  css  js  c++  java
  • 递归与分治策略(一)---算法设计与分析

    递归与分治策略(一)

    简而言之,递归就是自己调用自己。

    递归算法:直接或者间接地调用自身的算法。

    递归函数:用函数自身给出定义的函数。

    注意:每个递归函数都必须有非递归定义的初始值,以确保递归函数完成计算。

    下面通过两个例子来介绍递归的特点

    阶乘函数

    阶乘函数递归地定义为:

    n!=1   (n=0)   

    或者   

    n!=n(n-1)!  (n>0)

    下面用一段简单的Java代码实现

    这里是递归实现:

    public static int facterial(int n) {
    		if (n == 0)
    			return 1;
    		else if (n < 0)
    			return -1;//发生异常,退出
    		else
    			return n * facterial(n - 1);
    	}

    下面是迭代实现:

    public static int f(int n) {
    		if (n == 0)
    			return 1;
    		else if (n < 0)
    			return -1;//发生异常,退出
    		else {
    			for (int i = n - 1; i >= 1; i--) {
    				n *= i;
    			}
    			return n;
    		}
    
    	}

    分析比较一下两种实现方法:

    递归实现:时间复杂度O(n);空间复杂度O(n)

    迭代实现:时间复杂度O(n);空间复杂度O(1)

    比较可知两种实现的时间复杂度等价,空间复杂度递归占用的略大一下,但是代码的结构清晰度递归更清晰一些。

    下面进行第二个例子的讲解

    2 Fibonacci数列

    Fibonacci数列的递归定义为

    F(n)=1   (n=0,1)

    或者

    F(n)=F(n-1)+F(n-2)    (n>1)

    下面用一段简单的Java代码实现

    这里是递归实现:

    public static int fibonacci(int n ){
    		if(n<0)
    			return -1; //发生异常,退出
    		else if(n<=1)
    			return 1;
    		else 
    			return fibonacci(n-1)+fibonacci(n-2);
    	}

    下面是迭代实现:

    public static int F(int n){
    		if(n<0)
    			return -1; //发生异常,退出
    		else if(n<=1)
    			return 1;
    		else {
    			int f0=1,f1=1,fx=0;
    			for(int i=2;i<=n;i++){
    				fx=f0+f1;
    				f0=f1;
    				f1=fx;
    			}
    			return fx;
    		}
    	}

    分析比较一下两种实现方法:

    递归实现:时间复杂度O(1.618n次方);空间复杂度O(n)

    迭代实现:时间复杂度O(n);空间复杂度O(1)

    比较可知递归实现的时间复杂度已经非常大了,空间复杂度递归占用的略大一下,但是代码的清晰度递归更清晰一些。而真正使用起来递归实现的代码是无用代码,用n=40这个数测试一下便知,递归实现的耗时太长了,有兴趣的可以测试一下。

    下面归纳一下递归算法的特点:

    1.简单(结构清晰,可读性强)

    2.性能较低(相比较迭代而言)

    性能较低的原因有以下两点:

    需递归调用工作栈支持(无法避免)

    有可能出现子问题重叠现象(必须尽力避免)

     

    这里递归的主要知识点就讲完了,下面介绍一下文章标题的分治法。

    分治法的基本思想:

    (容易)分解->递归->(容易)合并

    分解:讲一个大规模的问题分解为多个规模较小的子问题,需要注意的是子问题必须互相独立并且与原问题相同。

    这里用一个例子进行讲解:归(合)并排序。

    这里留在下一篇文章介绍,睡觉咯,今天学到了这些,和大家分享一下,感谢大家的支持。

     

     

     

    我的CSDN博客地址:http://blog.csdn.net/yannanying
  • 相关阅读:
    Java子类和父类之间方法和属性关系
    静态链接库与动态链接库
    两人相遇问题时间段
    try catch finally
    shell判断条件参数过多
    python C++ Java 文件数据库等流操作,当打开后必须关闭
    CSS3 target 伪类不得不说那些事儿(纯CSS实现tab切换)
    清浮动方法
    this函数的理解
    css3 tranform  transition animation
  • 原文地址:https://www.cnblogs.com/yannanying/p/4342736.html
Copyright © 2011-2022 走看看