递归为什么难理解

今天温习了一遍树的先序遍历的非递归实现,对于递归的操作有了更深入的理解

1.首先说为什么递归”难”?

答:(1)其实递归中的临界条件下的简简单单的直接return都不仅仅是返回就这么简单了(注意这里我说的是简简单单的直接return,如果return 参数;那么在return出栈的时候还将数值传递给了递归调用的时候的变量考虑:

//问题:对于一个二叉树,设计一个算法遍历得到其深度:
int TreeDeep(BNode T)
{
    if(T == NULL)
        return 0;
    else
    {
        int l = TreeDeep(T->l);
        int r = TreeDeep(T->r);
        return l>r? l+1:r+1;//此时的return时行为(1)出栈(2)传参给上层栈帧的l或r
    }
}

)其内部隐示声明了一个条件——if(函数调用栈不空) { 返回上一层的函数;    继续上层函数执行的内容继续执行;} (2)递归中每次的函数调用也不是简简单单重复执行一遍函数那么简单,有稍微理解点的会说那在递归调用中传递的参数不一样,会改变函数的输入,不完全对,你这只是在第一层。实际上他执行了三步操作:-从(汇编)机器的角度来说:函数调用函数的时候会将调用的函数执行完的语句(注意这里并不是该语句的下一条语句,请考虑int a = RecusionFun(paremeter) + i ;的情况当RecusionFun执行完之后才会执行+i )的地址放在调用栈中,等到使用完会返回直接执行之后的语句。 ⭐️这三步分别是(1)传递新参数(2)将当前参数以及函数体内的变量入栈 (3)记录返回地址。其中前两部尤为重要。

正是·调用的时候传递新参数+入栈+记录返回地址。·return的时候传参 + 出栈 + 继续返回地址执行,这些隐藏的操作,才导致递归的难以理解,更进一步说递归就是栈的应用,而我们很多时候就忽视了这一点仅仅从递归能做什么直接切入而不清楚递归的原理,当然都是大学问,但是学习不应该循序渐进吗?

⭐️关于树的先序遍历递归和非递归的对比考虑如下代码:

//非递归:
关键操作:
if(node_p != null) //⇔ 递归的操作条件,则对变量进行操作
{
    Print(node_p);//⇔递归调用函数前的操作内容
    PushStack(node_p); //⇔递归调用函数时隐藏的入栈主调函数信息的操作
    node_p = node->left_child;//⇔递归调用函数时的传参(修改被调函数所传参数信息的操作)
}

if(node_p == NULL && !IsEmpty)//⇔递归的临界条件时 且 栈中仍有主调函数的情况
{    
    node_p = Pop(stack)//返回主调函数地址
    node_p = node_p->right_child;//继续向下执行新的被调函数传参
}

if(node_p == NULL && IsEmpty(st))
    return;
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值