递归及递归的特例

递归:

1.定义在一个函数过程中出现直接或间接调用函数本身,称为函数的递归调用。

eg:有一个学生在一起,问第五个学生有多少岁,他说比第4个学生大2岁。问第四

个人多少岁,他说比第三个人大两岁。问第三个人有多少岁,第三个人说他比第二

个人大两岁。问第二个人多少岁,第二个人说他比第一个人大两岁。第一个人10岁。

第一种解法:用循环

第二种解法

首先我们要了解递归的两大要素:

1)边界条件:确定递归何时终止,也称递归的出口

(2)递归模式:大问题是如何分解成小问题的,也称递归体.(缩小问题的规模)

假如我们要求第n个人的年龄,我们可以将这个问题分成n步:

(1):求第n个人的年龄

(2):求第n-1个人的年龄

(3):求第n-2个人的年龄

      ......

 (4):求第二个人的年龄

(5)求第一个人的的年龄

2.递归的典型例题

斐波那契数列:1 1 2 3 5 8 13 21.....

 我们可以通过上面的一组数列了解到斐波那契数列的规律:除了第一项和第二项为1,其他项就等于那一项的前两项之和。

由此我们可以得到:

然而斐波那契的数列是最不适合使用递归调用的。

我们还是通过这个例子分析:

(1):求第n个人的年龄

(2):求第n-1个人的年龄

(3):求第n-2个人的年龄

      ......

 (4):求第二个人的年龄

(5)求第一个人的的年龄

假如我们要求第五个人的年龄,那我们必须访问第四个人的年龄;我们想要知道第四个人的年龄,就必须访问第三个人的年龄;

我们想要知道第三个人的年龄,就必须访问第二个人的年龄;我们想要知道第二个人的年龄,就必须访问第一个人的年龄。这就是我们入栈的时候。

然而我们只知道第一个人的年龄并不知道其他人的年龄,所以在入栈的时候必须把其他人的年龄保存起来。

栈的特点:先进后出,后进先出

当我们知道了第一个人的年龄后,我们就可以以此类推求出第五个人的年龄。这就到出栈的时候。

我们可以通过上面几幅图发现,斐波那契的时间复杂度和kong空间复杂度都是O(n)。比我们用循环都要慢,所以斐波那契是最不适合用递归的数列。

我们ji介绍了最不适合用递归的例子,那我们就讲一下最适合用递归的例子。

3.最适合递归的例子

汉诺塔:古代有一个梵塔,塔内有3个座A,B,C,开始A座上有64个盘子,盘子大小不等,大的在下面,小的们在上面。有一个老和尚想要把这64个盘子从A座移到C座,但规定每次只能移动一个盘子,且在移动过程中始终保持大的在上面,小的在下面。在移动过程中可以利用B座,要求找出最简单的移动步骤。如图所示

我们通过画图得到这样一个规律:有N个盘子,那我们就需要移动2的n-1次。我们可以先将A座上的N-1个盘子通过B移到C上,再将A座上的盘子移到C上,然后通过A将B上的盘子移动C上。

 

算法:

#include<stdio.h> 
void Move(char x,char y)
{
    printf("%c-%c\n ",x,y);
}
int Hanoi(int n,char a,char b,char c)
{
    if(n==1||n==0)
    {
        Move(a,c);
    }
    else

    {
        Hanoi(n-1,a,c,b);
        Move(a,c);
        Hanoi(n-1,b,a,c);
        
    }

}
int main()
{
    Hanoi(1,'a','b','c');
    Hanoi(3,'a','b','c');
    return 0;
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值