大家好,我是茹小依。相信大家最初学习c++的时候,都被递归程序绕的七荤八素,但其实递归并不是什么洪水猛兽,在这篇文章里,小依酱将带领大家一起来看看递归程序后面蕴含的逻辑关系。
首先看一下递归的定义吧:程序调用自身的编程技巧称为递归(recursion)。简单来说,就是当一个程序中有许多重复的计算步骤时,我们可以编写一个程序只完成一步,随后的每一步都直接调用本身的程序,听起来是不是有点俄罗斯套娃的意思?
光看定义可能有点抽象,让我们来看具体的例子:
如果要求n的阶乘,我们定义一个函数f(n)来求n的阶乘,例如4的阶乘就是f(4),那我们可不可以表示成4*f(3),然后在表示成4*3*f(2),然后是4*3*2*f(1),这样循环调用同一个程序,最后只用算f(1)的值,f(4)也就相应求出。但是要注意的是:递归一定要有一个终止条件,在上面这个例子中,就是算到f(1)终止,终止完成后再一级级返回就可以了,相应的终止条件应该在函数中有所体现。
代码如下:
#include <iostream>
using namespace std;
long int f(int a);
int main()
{
cout<<f(4)<<endl;
return 0;
}
long int f(int a)
{
int sum=a;
if(a==1)//终止条件
return 1;
else
sum=sum*f(a-1);//递归过程以及递归向上返回过程
return sum;
};
简单来说,只要你找准结束条件和递归过程以及递归返回过程这三个部分,递归函数对你来说使用起来就是非常简单了吧。(结束条件要先写出来)
具体让我们再来看看比较难的例子。
求一颗二叉树的深度:
(图片来自百度百科)
先来看看这棵二叉树从根节点1来看,显然它的深度等于左后两棵树2和3最大的深度加一,那么我们如何求2和3的深度呢,同样2的深度为4和5的最大深度加一,这样算下去,我们就可以发现明显的递归过程。
先看结束条件,也就是当前节点左边和右边都没有分支时结束,表示这个节点到头,其长度已经求出来了。例如我们访问到7,7的左边没有分叉说明其长度为0,右边也没有也为0,而7的长度就返回为0+1。
程序如下:
int DepthBTree(BTreeNode *BT)
{
if(BT==NULL)
return 0;
else
{
int dep1=DepthBTree(BT->left);//递归过程:向左寻找长度
int dep2=DepthBTree(BT->right);//向右寻找长度
if(dep1>dep2)//递归返回过程:每向上返回一次,长度加一
return dep1+1;
else
return dep2+1;
}
}
如果你还是不太明白,或者想再看一个例子加深一下印象,那我们按照这三步再分析一个例子。
这次我们来寻找二叉树中的一个元素(bool类型函数):
(图片来自百度搜图)
例如我们来查找元素9:
1 结束条件:
结束条件有两种,一种是找到了,返回true,那么还有一种就是没找到返回false。
2 递归过程:
从根节点开始分叉成两半开始分别找两边,两边各分叉为两边开始找…
3 返回过程:
找到9一层层向上返回true,最终根节点处返回true·,如果没找到,一层层向上返回false,但这个false不会返回到根节点,画图思考一下为什么?
程序如下:
bool FindBTree(BTreeNode *BT,ElemType &x)
{
if(BT==NULL)
return false;//直到最后也未找到
if(BT->data==x)//找到了
{
x=BT->data;
return true;
}
else
{
if(FindBTree(BT->left,x))
return true;
if(FindBTree(BT->right,x))
return false;
return false;
}
}
聪慧如你,看懂了吗?
码字不易,关注一下专栏和作者吧(*╹▽╹*)。