数据结构与算法 10 递归理解(从内存角度深入剖析)

3.5 递归理解


什么叫 递归呢 ?

答:从形式上来看,递归 是函数调用自己方法本身的行为,叫做递归。而从 行为上来看,是 每次都递 过去有一定规律的有效的数据后,再 统统 归回来的 过程,这叫做 递归!

在学习递归之前,和传统的 学习方式不同!我们将 从内存的角度切入。深层次的剖析这个所谓的 在算法基础中最大的难点: “递归”

  1. 首先我们要知道 递归 是怎么实现的?即实现原理是什么?

答:递归 的实现原理 就是不断的 用同一个函数的模板,生成多个相同的函数 压入到 栈中!其 最先压入栈中的 函数 应 最后一个 弹出。 而我们 所谓的 把多个函数压栈的过程 称之为 “递” 的过程,从最晚 压栈的 函数跳栈. 到 最早压栈的函数 跳栈。这个过程 我们称之为 “归” 的过程。(这就是 从内存角度来分析的 "递归"

  1. 作用:

我们通常用 “递归” 来解决一个 有规律性的、大型的复杂问题。可以先把这个大问题当作父问题。然后将其转换为 一个与原问题相似的、规模较小的 多个 子问题。 不断的将 这些规模较小的问题,求解出来。然后最后总结这些 小问题的结果。再将其 转为 整个大问题 的最终结果!(递归是一种 解决问题的 策略!它可以用 少量的代码写出的程序来解决 很复杂的重复计算和多次判断的大问题。使其大大减少了我们程序的代码量。)递归的缺点 在于 占用的 内存空间 实在是 太多了。而且它 还不像 多线程那样 可以 同步处理。

  1. 递归的注意事项:

递归 最需要注意的事项 就是 "不要无限制的调用自己!否则会导致栈溢出!死循环!"通常我们 设计 递归,都分为三步骤。即 ①边界条件的 出口步骤、②压栈前执行的代码步骤、③跳栈后执行的代码步骤。

在这里插入图片描述

4. 如何正确的分析和写出递归 ?

① 需要知道自己用 递归要 完成 什么样的任务,解决什么样的问题。(换言之 就是你想要处理的问题,能不能用 递归来解决。)

如果可以用递归来解决,那么 第一步 需要 做什么?最后一步 又 需要做什么?中间 的压入的栈 是否可以 找到 相似的共同点?这是很关键的,而且要明确知道的是,根据设计压栈前后的代码部分,我们可以 灵活的决定 第一步需要做的事是 刚开始压入的时候做,还是弹出的时候做。如果是压入的时候做,那么就写到第一次压栈的函数里。如果是 弹出的时候做,那么 需要 把 它 设在 最后一次压栈的函数里,这是因为 最后一次压栈,是最先弹出的!!!

如何能够决定 每个压入栈的函数,执行它自己相应的代码。是 真正会用 递归的精髓!(往往 很多的老师,都会告诉你 递归 这个东西 需要找共同点。没错!但是不能 总是纠结于 共同点!!而是需要 知道 每个 压入栈的函数 都可能 有自己 独特的 处理方式。这才是 递归的魅力所在!)


3.5.1 递归的练习

  1. 求 n 的阶乘

技巧 ①:设计限制 递归的出口,可以 根据 该问题的最简单情况来设计!比如 n 的阶乘,最简单的情况 就是 当 n == 1 的时候,阶乘就是 1。

package com.muquanyu.algorithm.recursion;

public class TestA {
    public static void main(String[] args) {
        System.out.println(f1(10));
    }

    //计算 n 的阶乘
    public static int f1(int n)
    {
        //1 * 2 * 3 * ... *n
        //我们要压入 n 个栈
        if(n == 1)
        {
            return 1;//即 n == 1 的时候 可以直接返回 1
            //
        }
        //让 n 不断地 -1 然后 压入 栈,当压到 n == 1 的时候,则 正好是 10个 函数被压入进去。
        int ret = f1(n-1);//我这个 变量接取的就是 从 1 * 2 这种 的乘值 因为 我们的这个函数递归,返回的值
        //仅仅只有 ret * n 这样的 乘值。
        //我们 第一次 提供的 数 就是 最大的 那个 被乘数。那么 我们 需要最后一次 乘!
        return ret*n;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值