深入理解递归以及汉诺塔问题[数据结构]

一.深入理解递归

1.什么是递归?

递归就是一个函数直接或者间接的调用自己。

2.函数是如何完成调用的?

2.1主调函数调用被调函数前,要做3件事

1.主调函数将所有的实参、返回地址传递给被调函数
2.为被调函数的局部变量(包括形参)分配存储空间
3.将控制转移到被调函数入口。

2.2被调函数返回主调函数前,要做3件事

1.保存被调函数的额返回结果
2.释放被调函数所占的空间
3.依照被调函数保存的返回地址将控制权转移到主调函数

举例说明:

/**
    1.主调main()函数将实参5,printf("hello\n")的地址传递给被调函数保存
    2.为f()的n变量分配存储空间
    3.main()函数将控制权交给f()函数
*/
void main()
{
    f(5);
    printf("hello\n");
}
/**
    1.将被调函数的返回结果7保存起来
    2.释放变量n所占的空间
    3.根据保存的返回地址,将控制权转移到main()函数的printf("hello\n")处继续执行
*/
int f(int n)
{
    n=n+2;
    return n;
}

3.递归满足的2个条件

1.必须有一个明确的终止条件
2.该函数所处理的问题规模必须是递减的(不能越递归问题越大,解决不了)

4.递归和循环的关系

所有的循环都可以用递归实现,反之,所有的递归不一定能用循环实现。

递归:易理解、速度慢(函数间的调用,需要耗费时间)、占空间大(函数间的调用,需要占空间)

循环:不易理解、速度快、占空间很少

二.用递归解决阶乘问题以及1-100的相加求和问题

1.用递归解决阶乘问题

n的阶乘:n*!(n-1)
n-1的阶乘:(n-1)*!(n-2)
n-2的阶乘:(n-2)*!(n-3)
. . . . . .
1的阶乘:1

#include <stdio.h>
#include <stdlib.h>
//递归求阶乘
int mult(n)
{
    if(n==1)
    {
        return 1;
    }
    else
    {
        return n*mult(n-1);
    }
}
int main()
{
    int val=mult(3);
    printf("%d",val);
    return 0;
}

2.用递归解决1-100的相加求和问题

1-100的和:100+(1-99的和)
1-99的和:99+(1-98的和)
1-98的和:98+(1-97的和)
. . . . . .
1的和:1

#include <stdio.h>
#include <stdlib.h>
//递归解决相加求和问题
int mult(n)
{
    if(n==1)
    {
        return 1;
    }
    else
    {
        return n+mult(n-1);
    }
}
int main()
{
    int val=mult(100);
    printf("%d",val);
    return 0;
}

三、汉诺塔问题

汉诺塔的传说不详细讲了,没有听说过的请点击这里:汉诺塔

用递归的思想解决汉诺塔问题:
1.将问题分解为原子步骤:比如只有2个盘子的时候,该怎么办
2.找到递归的出口(当只有1个盘子的时候,直接移动到C柱)

#include <stdio.h>
#include <stdlib.h>
//递归处理汉诺塔(我们假设就2个盘子,3根柱子)
void Hanoi(int n,char A,char B,char C)
{
    //当A柱只有1个盘子的时候,从A柱直接移到C柱
    if(n==1)
    {
        printf("将编号%d的盘子从%c柱移到%c柱\n",n,A,C);
    }
    else
    {
        //将编号为2的盘子从A柱借助C柱直接移到B柱
        Hanoi(n-1,A,C,B);
        //将编号为1的盘子从A柱移动到C柱
        printf("将编号%d的盘子从%c柱移到%c柱\n",n,A,C);
        //再将2号盘子从B柱借助A柱移到C柱
        Hanoi(n-1,B,A,C);
    }
}
int main()
{
    Hanoi(3,'A','B','C');
    return 0;
}

四.递归总结

用递归思想处理问题:
1.首先我们要把问题的每一步分解开,分成原子的步骤
2.我们不用关心编写的递归函数是怎样实现的,因为我们在分解为原子步骤,用递归处理的时候,本身就实现了。
3.递归的实质是将规模为n的问题转换为规模为n-1的问题,n-1的问题转换为规模为n-2的问题,最后转换为可解规模的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值