函数递归,太难懂了。请解释停
函数递归,太难懂了。请解释下。
请输入一个50以内的自然数: 6
前6个自然数的和为:21
这个程序21 到底是如何算的?我猜测是 6+5+4+3+2+1=21
但是我不知道原理细节,这个a在这里到底起什么作用?是如何计算6+5+4+3+2+1=21的,能否用通俗易懂的来解释下???
a[n-1]+sum(a,n-1); //a[5] + sum(a,5);
a[n-1]+sum(a,n-1); //a[4] + sum(a,4);
a[n-1]+sum(a,n-1); //a[3] + sum(a,3);
a[n-1]+sum(a,n-1); //a[2] + sum(a,2);
a[n-1]+sum(a,n-1); //a[1] + sum(a,1);
a[n-1]+sum(a,n-1); //a[0] + sum(a,0);
------解决方案--------------------
调试时单步跟踪了吗?跟一次就明白了。
------解决方案--------------------
递归其实是便于理解的,你试着用最原始的思考方式想一下
------解决方案--------------------
递归。
就是函数的嵌套,但是必然有个条件结束嵌套。
所以必然有2个条件判断。一个嵌套,一个是结束嵌套。
------解决方案--------------------
在调用sum(a,n)时遇到sum(a,n-1).把sum(a,n)压入堆栈,然后先调用sum(a,n-1),又在其中发现sum(a,n-1-1),于是把sum(a,n-1)压入堆栈。以此类推,直到n==0;return 0;然后把在堆栈中的sum函数依次出栈,从而计算出最后结果。
------解决方案--------------------
递归就是自己调用自己,可能对初学者来说,稍微难理解一点。但是有些问题用它来解决是很方便的,而且反而会更好理解,比如二叉树的遍历之类的,但是递归是效率很低的,建议不采用
------解决方案--------------------
哎,递归害死人,纯粹是在炫耀技术,但是效率差,最简单的方法为什么不用,不是有数学家给了公式了不:
n*(n-1)/2
这样效率不是更加高吗????!!!!!
------解决方案--------------------
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出
------解决方案--------------------
哥,这个是尾递归,你查下尾递归就知道怎么回事了
------解决方案--------------------
a不仅是数组名还是数组第一个元素的地址(相当是一个指针)
return a[n-1]+sum(a,n-1) 这句话中sum(a,n-1)就是将原来的a[]重置为a(也就是返回原来的数组不改变),n-1就是将原来的n重置为n-1
明白了没有!同为大学生,共勉!
------解决方案--------------------
函数自己调用自己,嵌套的函数,有一个结束嵌套条件,条件后再依次按照原嵌套顺序返回
------解决方案--------------------
就是函数不断的调用它自己,完成栈操作。。
#include<iostream>
using namespace std;
#define N 50
int sum(int a[],int n);
int main()
{
int i,n,a[N];
printf("请输入一个50以内的自然数:");
scanf("%d",&n);
for(i =0;i<n;i++)
a[i]=i+1;
printf("前%d个自然数的和为:%d\n",n,sum(a,n));
return 0;
}
int sum(int a[],int n)
{
if(n<=0)
return 0;
else
return a[n-1]+sum(a,n-1); //递归求前n个数的和。
}
请输入一个50以内的自然数: 6
前6个自然数的和为:21
这个程序21 到底是如何算的?我猜测是 6+5+4+3+2+1=21
但是我不知道原理细节,这个a在这里到底起什么作用?是如何计算6+5+4+3+2+1=21的,能否用通俗易懂的来解释下???
a[n-1]+sum(a,n-1); //a[5] + sum(a,5);
a[n-1]+sum(a,n-1); //a[4] + sum(a,4);
a[n-1]+sum(a,n-1); //a[3] + sum(a,3);
a[n-1]+sum(a,n-1); //a[2] + sum(a,2);
a[n-1]+sum(a,n-1); //a[1] + sum(a,1);
a[n-1]+sum(a,n-1); //a[0] + sum(a,0);
------解决方案--------------------
调试时单步跟踪了吗?跟一次就明白了。
------解决方案--------------------
递归其实是便于理解的,你试着用最原始的思考方式想一下
------解决方案--------------------
递归。
就是函数的嵌套,但是必然有个条件结束嵌套。
所以必然有2个条件判断。一个嵌套,一个是结束嵌套。
------解决方案--------------------
在调用sum(a,n)时遇到sum(a,n-1).把sum(a,n)压入堆栈,然后先调用sum(a,n-1),又在其中发现sum(a,n-1-1),于是把sum(a,n-1)压入堆栈。以此类推,直到n==0;return 0;然后把在堆栈中的sum函数依次出栈,从而计算出最后结果。
------解决方案--------------------
递归就是自己调用自己,可能对初学者来说,稍微难理解一点。但是有些问题用它来解决是很方便的,而且反而会更好理解,比如二叉树的遍历之类的,但是递归是效率很低的,建议不采用
------解决方案--------------------
哎,递归害死人,纯粹是在炫耀技术,但是效率差,最简单的方法为什么不用,不是有数学家给了公式了不:
n*(n-1)/2
这样效率不是更加高吗????!!!!!
------解决方案--------------------
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出
------解决方案--------------------
哥,这个是尾递归,你查下尾递归就知道怎么回事了
------解决方案--------------------
a不仅是数组名还是数组第一个元素的地址(相当是一个指针)
return a[n-1]+sum(a,n-1) 这句话中sum(a,n-1)就是将原来的a[]重置为a(也就是返回原来的数组不改变),n-1就是将原来的n重置为n-1
明白了没有!同为大学生,共勉!
------解决方案--------------------
函数自己调用自己,嵌套的函数,有一个结束嵌套条件,条件后再依次按照原嵌套顺序返回
------解决方案--------------------
就是函数不断的调用它自己,完成栈操作。。