算法学习之递归

本文深入探讨了递归和分治算法的概念及其应用,通过斐波那契数列和全排列问题,详细解析了递归算法的设计思路与实现方法,强调了边界条件和递归式的设定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法学习第九篇

谈到递归,就要谈谈分治,分治也叫分而治之,意为将一个大问题分解为若干个小问题然后逐个击破,最后合并所以子问题的解得到原问题的解,总体概括出来就是三步:分解、解决、合并,但需要注意的就是我们面对的子问题应该是相互独立的。

递归

递归思想是很适合用于实现分治算法的,子问题的求解过程相同,则我们可以通过重复调用自身的函数,从而得到我们想要的答案,虽然使用递归算法在实际编程中不太推崇主要是因为时间复杂度太高,对于实际的项目编写效率低,,但这种解题思想是非常值得推崇的,包括后面的动态规划问题也是有所体现的。在实现递归时候必须注意两个必要点①边界设置②递归式(也就是分解为若干子问题的手段)

比较经典的例子就是斐波那契数列问题,斐波那契数列是满足f(0)=1,f(1)=1,f(n)=f(n-1)+f(n-2)的数列,显然如果我们求解f(n)就可以分解为求解f(n-1)和f(n-2),以此类推继续求解下去,遵从f(n)=f(n-1)+f(n-2)即可。代码如下

#include <cstdio>
int f(int n)
{
    if(n==0||n==1)
        return 1;
    else
        return f(n-1)+f(n-2);
}

int main()
{
    int n;
    scanf("%d", &n);
    printf("%d", f(n));
    return 0;
}

全排列问题

全排列:把1~n的n个整数进行不同顺序排列,所有的排列组合成为全排列,例如(1,2,3,4)全排列为(1234)(1243)(1324)(1342)(1423)(1432)(2134)(2143)(2413)(2431)(2314)(2341)(3124)(3142)(3412)(3421)(3214)(3241)(4123)(4132)(4213)(4231)(4312)(4321)

分析:首先思考边界,定义数组a[n]当做我们的存储数组用来存储得到的排列,定义j为数组下标,也是我们要处理的下标位置,依次递增,增大到n+1是其实已经完成所有的处理,所以边界就是j==n+1,当j==n+1时候输出当前序列,第一步已经解决。第二就是思考递归式,从数组第一位开始着手,从1~n里面选择一个作为首位,但进行到第二位时候怎么排除已经使用过的第一位的数字呢,答案很简单——散列,先定义一个散列hashtable[n],里面都置为false,当使用一个数字后就在该数字位置置为true,分析完了之后,递归继续进行下一位的分析,代码如下:

#include <cstdio>
const int max=20;
int n, a[max], hashtable[max]={false};
void quanpai(int j)
{
    if(j==n+1)     //j相当于a数组指针
    {
        for(int i=1;i<=n;i++)    //边界
        {
            printf("%d", a[i]);
        }
        printf(" ");
        return;
    }
    for(int x=1;x<=n;x++)
    {
        if(hashtable[x]==false)
        {
            a[j]=x;
            hashtable[x]=true;
            quanpai(j+1);
            hashtable[x]=false;
        }
    }
}

int main()
{
    scanf("%d", &n);
    quanpai(1);
    return 0;
}


皇后问题

待更..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值