关于递归树的理解和学习

起源

一直感觉递归蛮绕,所以想学习下

例子

查看资料,大部分讲递归都用到斐波那契数列,那我也用这个例子吧,公式是F(n) = F(n-1) + F(n-2)

树图

在这里插入图片描述

解释

执行流程

如图所示,这是整个执行流程,每一个结点头上都有一个数字代表是第几次调用F函数,聪明的小伙伴已经看出来这个是二叉树的先序遍历(根,左,右),不难看出,只有在叶子节点(没有子节点的节点)上才返回值,也就是F(0)F(1),返回了5个F(1)和3个F(0),所以结果是5

返回流程

那么具体是怎么返回的呢,当执行到第5个节点时 F(1)返回了1,然后等待第6个节点F(0)一起做运算
F(1) + F(0),并且返回给F(2)
, 那么此时第四个F(2)节点已经有值了,但是他并不能返回,因为他要等第7个节点的值 一起做公式运算 F(2)+F(1),其他节点依次类推,然后一直到返回到根节点F(5)

代码演示

代码

public class Test3 {
    // F()函数一共执行的次数,和上面的树节点个数对应
    static int count = 0;

    public static void main(String[] args) {
        F(5);
        System.out.println("一共执行F()次数:" + count);
    }

    public static int F(int n) {
        count++;
        System.out.println("进来的是===" + n);
        /*
         * 小于0是为了 避免初始 n 为负数
         * 等于0是为了考虑边界情况
         * */
        if (n <= 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        return F(n - 1) + F(n - 2);
    }

}

结果

在这里插入图片描述

总结

递归函数一般分成两个部分,一个是边界处理,一个是公式,边界处理就是 那些对应的返回具体值的部分,对应上面的是两个if语句,公式就是两个数之间存在什么关系,用一个公式表示出来,然后如上面的树图所示,一直先序遍历到叶子节点,然后才返回值,最后所有叶子节点返回的总和(这个例子是总和,其他的如阶乘就不是了,总之就是叶子节点做一些运算返回给各自的根节点,然后一直返回到根节点)就是要求的F(n)。

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
递归(Recursion Tree)是一种可视化递归算法的方式,它通过将递归算法转化为形结构来帮助我们更好地理解递归算法的执行过程和时间复杂度。 在递归算法中,每次递归调用都会产生一个新的子问题,直到达到基本情况,然后逐级返回结果。这样的递归过程可以用一棵来表示,其中每个节点代表一个递归调用,子节点代表对应的子问题,叶子节点代表基本情况的返回值。 举个例子,假设我们要求一个数组的所有子集,可以使用如下的递归算法: ``` void subsets(vector<int>& nums, int start, vector<int>& subset, vector<vector<int>>& res) { res.push_back(subset); for (int i = start; i < nums.size(); i++) { subset.push_back(nums[i]); subsets(nums, i+1, subset, res); subset.pop_back(); } } vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> res; vector<int> subset; subsets(nums, 0, subset, res); return res; } ``` 我们可以将递归过程可视化为下面的递归: ``` [] / | \ [1] [2] [3] / \ / \ | [1,2] [1,3] [2,3] [3,4] [1,2,3] / \ | [1,2,3] [1,3,4] [2,3,4] ``` 其中,[]代表一个子集,每个节点代表一次递归调用,左子节点代表将当前元素加入子集,右子节点代表不将当前元素加入子集。当递归到数组末尾时,就返回一个空子集。 通过递归,我们可以更好地理解递归算法的执行过程,并且可以根据递归来分析时间复杂度。在上面的例子中,递归的深度为数组的长度N,每个节点会被访问一次,因此时间复杂度为O(2^N)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值