递归算法

318 阅读2分钟

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」。

递归算法

递归的基本概述:

递归的定义:

递归算法通过重复将问题分解为同类的子问题而解决问题的方法,个人认为递归的基本思想就是自己调用自己。需要注意的是使用递归时必须要有一个结束条件,也就是递归出口。

递归的优缺点:

优点

递归算法会使代码很简洁。

缺点

  • 递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出

  • 递归运行效率较低。所以一般不提倡用递归算法设计程序。

  • 递归算法的时间复杂度是O(n^2),所以也是比较暴力破解算法。

function recursion(大规模){
    if (end_condition){      // 明确的递归终止条件
        end;   // 简单情景
    }else{            // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
        solve;                // 递去
        recursion(小规模);     // 递到最深处后,不断地归来
    }
}

例题

斐波那契数列

斐波那契数列如下: 1,1,2,3,5,8,13,21,34,...

int fib(int n)//用到函数,使用函数时注意的形参和实参的区别
{
    if(n==1 || n==2)//确定前两个数,也是递归的出口
        return 1;
    else
        return Fib(n-1)+Fib(n-2);//使用了递归,递归就是自己调用自己,是一种非常简便的写法
}
#include<iostream>
using namespace std;
int main()
{
    //斐波那契数列第一种解法,F(n)=F(n - 1)+F(n - 2)
    int n;
    cin>>n;//输入需要得到斐波那契数列的第几项
    int a=1,b=1;,i=1;//a,b是数列的第一、二个值,i是用来判断第几项的数值
    while(i<n)//知道i大于n才结束循环,相当于求得第n项的值后结束
    {
        int c=a+b;//c指下一项
        a=b;//令第i项的第二个元素作为第i+1项的第一个元素,即n-2项
        b=c;//将目前第i项的值作为i+1项的第二个元素,即n-1项
        i++;//将i的值加一,保证循环可以退出,并且求第i+1项的数值
    }
    cout<<a<<endl;
    return 0;
}

第一种是递归方法,第二种是非递归方法。明显可以看出第一种比第二种代码更简洁,更精炼。然而效率却没有第二种高

杨辉三角

  /**
    * Title: 杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数。
    * 它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。
    * 
    * 例如,下面给出了杨辉三角形的前4行: 
    *    1 
    *   1 1
    *  1 2 1
    * 1 3 3 1
    */
    public static int getValue(int x, int y) {
        if(y <= x && y >= 0){
            if(y == 0 || x == y){   // 递归终止条件
                return 1; 
            }else{ 
                // 递归调用,缩小问题的规模
                return getValue(x-1, y-1) + getValue(x-1, y); 
            }
        }
        return -1;
    } 

之后遇到递归类型的算法题目会更新,目前就讲解到这里。