平时递归用的多吗?怎么不理解递归?看程序能看懂别人的递归可是自己写的时候却不行了(写不了)?

平时递归用的多吗?怎么不理解递归?看程序能看懂别人的递归可是自己写的时候却不行了(写不了)?,第1张

递归你需要先找到递归的递归条件和终结条件。

递归的基本规则可以解释为:

如果条件为继续递归

为条件做一定变换后调用自身

否则

返回基本值

当然,可能会出现更复杂的,但一般都是这样。所以需要找到三个地方:

第一、就是在什么条件下要继续递归,在什么条件下结束递归。

第二、递归时需要做什么变换才能让递归函数最终走到终结条件。

第三、基本值是什么。

比如递归计算N!。我们知道函数基本写作

int func(int n)
{
    if(n > 1)
        return n  func(n - 1);
    else
        return 1;
}

针对这个函数,三点就是:

第一、递归条件就是只要n不等于1,则递归继续,否则递归终结。

第二、递归变换就是n-1。

第三、终结时,基本值是1。

更复杂的递归也是符合这些条件的,只不过可能不止一种变换或不止一种终结条件等等。

求采纳哦

递归函数即自调用函数,在函数体内部直接或间接地自己调用自己,即函数的嵌套调用是函数本身。
例如,下面的程序为求n!:
longfact(intn)
{
 if(n==1)
 return1;
 returnfact(n-1)n;//出现函数自调用
}

递归函数就是在函数的内部调用它自身。例如求1-100的和
int
fun(int
n)
{
if(n=1)
return
1;
else
return
n+fun(n-1);
}
就是说前n项和可以分解为,n加上前n-1项和,而前n-1项和可以分解为n-1加上前n-2项和。如此循环。
即:sum
=
fun(100)=n+fun(100-1)=n+(n-1)+fun(n-2)
=n+(n-1)+(n-2)+fun(n-3)
=n+(n-1)+(n-2)+(n-3)++3+2+1;
类似这种可以这样分解的问题都可以用递归函数来实现。
比如:阶乘,等

首先你得理解递归的作用或目的。当一个问题比较复杂时,我们设法将他转化为一个或多个形式一样但问题规模较小的问题来解决,并且当小问题解决后能够推导出大问题的解。若小问题仍然无法解决则继续将小问题转化为形式相同的更小问题,直到问题规模小到足以轻而易举地解决。这里将一个大问题转化或者说分解出的小问题称为该大问题的子问题。
而循环中的递归可以认为是在分解问题的过程中将问题分解为了多个而不是一个子问题,而原问题的解是这多个子问题的解的和(或组合、合集之类的),所以你要用循环来将子问题的解进行求和或组合。
在你给的这个例子中,由于求的是组合,那么可以知道123和312是相同的组合,所以只需求其中的一种,这里是规定只求组合中的数是递增的那种。因此对测试数据{1,2,3,4,5,6}可以这么理解这个问题:
{1,2,3,4,5,6}中取4个数的所有组合 =
第一个数取1,后三个数为{2,3,4,5,6}中取3个数的所有组合
+ 第一个数取2,后三个数为{3,4,5,6}中取3个数的所有组合
+ 第一个数取3,后三个数为{4,5,6}中取3个数的所有组合
这里当三个子问题求解出来以后,你就需要用循环将他们加起来不是么!
注意这里的三个子问题分别是{2,3,4,5,6}中取3个数的所有组合、{3,4,5,6}中取3个数的所有组合、{4,5,6}中取3个数的所有组合。这样看他们才和原问题有相同的形式。那么将第一个子问题再进行分解:
{2,3,4,5,6}中取3个数的所有组合 =
第一个数取2(全局来看是第二个数取2),后2个数为{3,4,5,6}中取2个数的所有组合
+ 第一个数取3(全局来看是第二个数取3),后2个数为{4,5,6}中取2个数的所有组合
+ 第一个数取4(全局来看是第二个数取4),后2个数为{5,6}中取2个数的所有组合
以此类推……
当递归到了某种情况,比如:第一个数取4(全局的第四个数取4),后0个数为{5,6}中取0个数的所有组合,那么这个子问题是不是轻而易举地解决了呢,因为取0个数表示你什么都不要做就将它解决了对吧,那么这时将前面选的四个数输出就是原始问题所要的其中的一个组合了。
下面讲下代码吧。
//arr为原始数组
//start为遍历起始位置
//result保存结果,为一维数组
//count为result数组的索引值,起辅助作用(也可理解为剩余还要选择几个数)
//NUM为要选取的元素个数
//arr_len为原始数组的长度,为定值
//============
由于每次递归调用时arr、result、NUM、arr_len四个参数的位置都是原封不动的传递下去,因此可以为了方便将它们作为全局变量,从而将他们移除出函数的参数列表
//============
void combine_increase(int start, int count)//在start到末尾的这个集合中选取count个数的组合
{
int i = 0;
for (i = start; i < arr_len + 1 - count; i++)//循环枚举第一个数的选择
{
result[count - 1] = i;//第一个数选择i(子问题中的第一个,全局的第NUM-count+1个),这里他选择倒着存放,即当还有四个数要选时,选择的第一个数放在result[3];当还有1个数要选时,选择的第四个即最后一个数放在result[0]
if (count - 1 == 0)//若在选择了一个数后剩余要选择的数的数量为0
{//那么可以输出了
int j;
for (j = NUM - 1; j >= 0; j--)//倒序遍历result输出吧
printf("%d\t",arr[result[j]]);
printf("\n");
}
else//还没选完?
combine_increase( i + 1, count - 1);//在i+1到末尾的这个集合中选取count-1个数的组合
}
//当函数返回时表示一个子问题得以解决了,那么返回上一层递归,循环中的i++,即选取下一个数作为上一层那个问题中的第一个数,去解决另一个子问题吧!
}

这不就是在二叉排序树上的递归查找,看程序
tree&
find(const
T&
d,
tree&
t){
if(t==NULL)
return
t;如果二叉树为空则返回空,查找失败
if(t->data==d)
return
t;否则,如果当前根结点关键码为d,则查找成功,当前根结点为待查找结点
if(d>t->data)
return
find(d,
t->right);如果比根的关键码大就递归查找右子树
return
find(d,
t->left);如果比根的关键码小就递归查找左子树
}
二叉树的递归定义的含义就是非空二叉树,除了根以外,左右子树都是二叉树(可以为空)


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/10545881.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-09
下一篇2023-05-09

发表评论

登录后才能评论

评论列表(0条)

    保存