首页 > 其他分享 >对递归的理解

对递归的理解

时间:2023-04-25 16:45:04浏览次数:34  
标签:递归 int move hanoi char 理解 盘子

  二叉树中的遍历以及线索二叉树的创建对递归的使用非常频繁,递归对我来说也一直是模糊不清的概念。

  故写下此篇文章帮助理解递归。

一.递归的定义

  "一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层,当最内层的函数执行完毕后,再一层一层地由里到外退出。"

  简要概括,如果一个函数在内部调用了自己,那么就可以之为递归。

二.对递归的理解

  

  递归包含两个要素:关系出口(也就是说,形成递归的函数一定包含着某种规律,找到这种规律,再确定出口就可以确定一个递归)

  住:出口不一定只有一个(如:斐波那契数列有两个出口)

三.程序的实现

  一般需要先将递归函数出口的判断写在前面,然后再写函数的关系式

#include <stdio.h>

int f(int n)
{
    if (n == 1)
    {
        return 1;
    }
    else
    {
        return f(n - 1) + n;
    }
}

int main()
{
    printf("%d",f(100));
}

四.汉诺塔问题

  

  (要求:将A中的盘子经过B全部移动到C中,并且在移动过程中大盘子不能在小盘子上面)

  解法:(1)当只有一个盘子时,直接将盘子从A移动到C即可,即move(A,C),这也就是递归的出口

     (2)当有多个盘子时,可以看成两部分,最下面的盘子是一部分,上面的所有盘子加起来是一部分,这样的话,就可以看做是上面所有盘子通过C移动到B,即hanoi(n-1,A,C,B),此                              时只需将A上的盘子移动到C即可,即move(A,C),接下来需要将B上剩下的n-1个盘子通过A移动到C上,所以再执行一次递归,hanoi(n-1,B,A,C)

#include <stdio.h>

void move(char a,char b)
{
    printf("%c -> %c\n",a,b);
}

void hanoi(int n,char A,char B,char C)
{
    if(n==1)
    {
        move(A,C);
    }
    else
    {
        hanoi(n-1,A,C,B);
        move(A,C);
        hanoi(n-1,B,A,C);
    }
}

int main()
{
    
    hanoi(3,'A','B','C');
    return 0;
}

五.总结

  递归的核心思想是找到出口以及规律,并将规律转换成函数表达式,而在我看来,找到规律的核心就是把部分看成整体(如汉诺塔问题,将上面的n-1个圆盘看成整体),然后对部分进行递归操作,最后得到整体的答案。

标签:递归,int,move,hanoi,char,理解,盘子
From: https://www.cnblogs.com/ryuichi-ssk/p/17353080.html

相关文章

  • 深入理解C#泛型:new与where关键字全解析
    C#泛型中new和where是重要的关键字,它们都可以用于约束泛型类型参数的限制;它们都用于提高代码的安全性和可用性,它们的作用在很大程度上提高了代码的可读性和可维护性。在这篇文章中,我们将一起了解泛型中的new和where,以及它们之间的区别。1.new关键字在C#泛型中,new关键字被用于指......
  • 视频理解串讲
     这是一篇早期论文提到的fusion方法,有lateearly,所以自然就想到slow,但实际上结果差别不大,甚至还不如手工特征,可见特征工程重要性这篇文章作者采用了一个早期的类注意力机制,人为强制的将图片中心裁剪出来进行识别,当然这是假设我们关心的对象大概率出现在图片中心 第二个工作......
  • GitLab-理解里程碑(史诗)/议题,评论/主题,代码建议
    1、里程碑:  可以理解为对大的工作内容进行定义,比如构建一个版本、新增某个功能、变更某个需求。2、议题:  为对“里程碑”进行进行模块拆分,比如变更某个需求时设计到多个端进行修改、多个接口修改、多个接口修改时又涉及到其他系统业务场景进行测试。可对这些内容进行拆分,并......
  • 五分钟理解Java算法的时间复杂度
    关注我了解更多Java技术知识,带你一路“狂飙”到底!上岸大厂不是梦!前言时间复杂度主要是为了反映函数的执行时间随着输入规模增长而变化的规律,在一定程度上可以体现程序的执行效率和算法的优劣。作为程序员,掌握基本的算法时间复杂度的计算是很有必要的。时间复杂度介绍理论上,执......
  • 参数与非参数检验:理解差异并正确使用
    数据科学是一个快速发展的领域,它在很大程度上依赖于统计技术来分析和理解复杂的数据集。这个过程的一个关键部分是假设检验,它有助于确定从样本中获得的结果是否可以推广到总体。在这篇文章中,我们将探讨参数与非参数检验之间的区别,提供示例以更好地理解它们的用例,并总结关键要点。......
  • 二叉树的遍历(递归算法)
    //二叉树的遍历(递归算法)#include<stdio.h>#include<malloc.h>typedefstructBiTNode{intdata;structBiTNode*lchild,*rchild;//存储二叉树的左孩子和右孩子}BiTNode,*BiTree;voidInitTree(BiTree&root){root=(BiTNode*)malloc(sizeof(BiTNo......
  • [教育题[持续更新]]自用理解
    牛客:猫猫与数列首先想的是直接暴力求解,则答案会导致溢出,然后等式两边同时加上log(以2为底)来防止溢出,并且能进行判断if(a[n-1]*log(a[n-2])>M){cout<<n-1<<endl;break;}当然这种情况一是成立时用的,else呢?则应该用longlong来......
  • php递归遍历文件目录
    美日汇:www.hnzyxok.com手机端:www.hnzyxok.com/i递归遍历文件目录(大体的思路就是:传入一个文件名后输出遍历所有内容,等发现文件还是个文件夹的时候接着递归调用当前的遍历方法,如果不是文件夹就输出文件名)functiondakai($mulu){$mydir=dir($mulu);echo"<ul>\n";while($file......
  • ssm框架整合 理解及搭建
    如何开发一个java-web的开发模式。三大块前端后端存储。分层,首先用户的请求到view,view调后端controller,controller业务逻辑处理存储,数据模型层model。按照这种模式开发。用框架实现mvc。目前用springmvc,最早期的controller层用的是struts1,servlet,再往后是struts+hibern......
  • 推动变革,打造全新的全面预算管理解决方案
    企业在迈向可持续的数字化进程时,其数字战略很少能够跟得上甚至超过业务需求。一些企业可能会尝试将现有的流程和技术在短期内加速整合,以减少现实差距。但从长远来看,这种方式可能会影响企业的效率、增长和敏捷性。因此,思考如何改进流程、正确处理技术变革,才能够促进更有效的数字化转......