关于递归的一点理解

一、递归的引入

可以先参考:对于递归有没有什么好的理解方法? - 知乎

递归算法讲解_LightOn-CSDN博客_递归算法

递归,包含递去和归来两个过程。递归跟数学归纳法有不少相似之处。可参考:递归与数学归纳法_野生码农-CSDN博客

1.递归的格式

1.终止条件
一定与输入的参数有关。终止条件决定了递归的深度

2.终止条件处理方法
决定了最后的返回内容

3.递归内容
即明确递归函数是如何调用自己的

2.如何才能写出递归函数

个人感觉递归是需要有经验支撑的。链表、树、字符串或者数字问题,不同的递归问题有不一样的套路,需要结合相应的递归问题总结出如何找出相应的递归套路。 

递归问题都可以转换成迭代问题,递归的效率通常比较低,但是代码更短、相对也更好维护。面对较为复杂的问题要写出递归会是一个抽象难受的过程,可能想一天都想不明白。

二、尾递归

通过递归,最近还了解到了尾递归,感觉这是个神奇的东西呀,效率高、代码简洁。

参考:递归算法转换为非递归算法的技巧 - coderkian - 博客园

递归和尾递归的区别和原理_ZMyths的博客-CSDN博客_尾递归

几种方法的尾递归实现 - ChuckLu - 博客园

1.个人浓缩提炼一下:

1)尾递归效率很高,接近迭代

2)尾递归为什么效率这么高?因为编译器会识别他是尾递归会对其进行优化以达到不压栈不浪费存储空间。

3)尾递归只需向下递去,不需要归回

2.尾递归的形式

举个斐波那契数列的例子

    int fib(int n) {
        return tail(n,1,2);
    }
    int tail(int n,int first,int second)
    {
        if(n==2)return second;
        if(n==1)return first;      
        return tail(n-1,second,first+second);
    }

1)在tail函数中实现尾递归。尾递归中的参数形式为tail(depth,other parameter...)。

2)depth即记录深度的参数,通过depth来作为一个结束条件终止递归。

3)other parameter即其他参数集合,最终要返回的值来自于other parameter中的一个。

4)tail函数return返回的很单纯,没有掺其他杂质,只return一个完整的递归表达式。

5)尾递归把迭代融合进了他的参数中了(即通过参数完成迭代的过程),这便是尾递归的精髓和最难的地方,如何写出尾递归的参数是最大的工作量。写尾递归返回函数的参数的时候要结合迭代进行思考

3.再举个例子

翻转整数

     //尾递归形式
int reverse(int num) {
    return tail(num, 0);
}
int tail(int num, int ans) {
    if (num == 0) return ans;
    return tail(num / 10, ans * 10 + num % 10);
}
     //迭代形式
int reverse(int num) {
    int ans = 0;
    while (num != 0)
    {
        ans = ans * 10 + num % 10;
        num /= 10;
    }
    return ans;
}

在这里,num记录深度,ans是要返回的参数。是不是感觉只要写出迭代表达式就能写出尾递归的表达式了?

猜你喜欢

转载自blog.csdn.net/qq_42987967/article/details/121704414
今日推荐