Algorithms_算法思想_递归篇

*爱你&永不变心* 提交于 2020-01-12 21:55:33


在这里插入图片描述


引导案例

案例一:

分销系统的返利: 比如B是A的下线,C是B的下线,那么在分钱返利的时候A可以分B,C的钱,这时候我们是不是就要分别找B,C的最后上级。这个问题我们一般怎么来解决呢?

C–>B–>A


案例二: .斐波那契数列:

1 1 2 3 5 8 13 21 ......

有什么特点?
从第三个数开始 就等于前面两个数相加;

数论思想:利用数学公式或者定理或者规律求解问题;

算法思想中最难的点:递归+动态规划

树论中(比如二叉树,红黑树)和递归密不可分,所以递归一定要弄明白了。


递归的定义

递归算法是一种直接或者间接调用自身函数或者方法的算法。

通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。

举个生活中的例子

比如我们在某窗口排队人太多了,我不知道我排在第几个,那么我就问我前面的人排第几个, 因为知道他排第几我就知道我是第几了。但前面的人也不知道自己排第几那怎么办呢?他也可以继续往前面问,直到问到第一个人,然后从第一个人一直传到我这里 我就很清楚的知道我是第几了

以上这个场景就是一个典型的递归。我们在这个过程中大家有没有发现一个规律那么就是会 有一个问的过程,问到第一个后有一个回来的过程吧。这就是递(问)加归(回)

那么这个过程我们是不是可以用一个数学公式来求解呢?那这个数学公式又是什么?

f(n)=f(n-1)+1
  • f(n):表示我的位置
  • f(n-1):表示我前面的那个人;

说白了 一个一个往前问 就是自己调用自己,完成这个功能。

推导出公式: f(n) = f(n-1) + f(n-2)


什么样的问题可以用递归算法来解决

需要满足的条件才可以用递归来解决?

(1)一个问题的解可以分解为几个子问题的解:

子问题,我们通过分治的思想可以把一个数据规模大的问题,分解为很多小的问题。
我们可以把刚刚那个问前面的那个人看为子问题。大化小

(2)这个问题与分解之后的子问题,求解思路完全一样:

(3)一定有一个最后确定的答案,即递归的终止条件。

刚刚那个问题就是第一个人。第一个人是肯定知道自己排第几吧即n=1的时候,如果没有这个特性那么我们这个递归就会出现死循环,最后程序就是栈溢出;StackOverflowError

递归并不是马上返回,而是一层一层的保存在Stack里边,满足结束条件后才一层一层的返回.


递归如何实现以及包含的算法思

递归,回溯(归的过程);

递归的关键相信大家已经知道了就是要(1)求出这个递归公式,(2)找到终止条件

现在我们可以回到课堂前跟大家讲的那个斐波那契数列数列:
1 1 2 3 5 8 13 这个的数列我们称之为斐波那契数列

按照我们说的 两个点 ,来分析一下:

求解公式:f(n)=f(n-1)+f(n-2)
终止条件:n<=2 也就是f(n)=1


斐波那契数列代码实现

分析一下,给定一个值n , 输出 n个数字组成一个斐波那契数列

从n开始,一直往前递归,直到符合终止条件即可。



public class Fibonacc {

    public static int fab(int n){
        if(n <=2 ) return 1; // 终止条件
        return fab(n-1) + fab(n-2); // 递归公式
    }

    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            System.out.println(i + ":" + fab(i));
        }
    }
}

在这里插入图片描述


递归的时间复杂度(2^n)和空间复杂度(2^n

代码实现了,我们来分析下 递归的复杂度

以斐波那契数列为例为分析递归树:

f(n)=f(n-1)+f(n-2)

在这里插入图片描述

图一画,一目了然 , 时间复杂度 2^n

空间复杂度的话,递归并不是马上返回,而是一层一层的保存在Stack里边,因为还有一个 归的过程,满足结束条件后才一层一层的返回. 空间复杂度自然也是 2^n

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!