C++:函数的递归调用相关
8个例子:<抄来的>
1、
//file 递归函数例1.cpp
//递归函数实现逆向输出数组a[]中的各元素值
#include"iostream.h"
void fun(int a[],int len)
{
if(len==1) {
cout<<a[0]<<endl;
return;
}
else{
cout<<a[len-1]<<" ";
fun(a,len-1); //recursive function call
}
}
void main(void)
{
int b[]={1,2,3,4,5,6,7,8,9,10};
fun(b,10);
}
2、
//file 递归函数例2.cpp
//递归函数实现求数组a[]中元素的最大值
#include"iostream.h"
int maxofarray(int a[],int len)
{
if(len==1)
return a[0];
else
return a[len-1]>maxofarray(a,len-1)?a[len-1]:maxofarray(a,len-1);
}
void main(void)
{
int b[]={12,2,3,4,5,16,1,8,9,7};
cout<<maxofarray(b,10)<<endl;
}
3、
//递归函数例3.cpp
//计算整数和:1+2+3+4+...+n。
long sum(int n)
{
if(n==1) return(1);//递推结束条件
return(sum(n-1)+n);//递推过程
}
#include"iostream.h"
void main(void)
{
int n;
cout<<"please input an integer n for calculating 1+2+3+4+...+n:";
cin>>n;
cout<<"the sum of 1+2+3+4+...+n is:"<<sum(n)<<endl;
}
4、
//递归函数例4.cpp
//计算整数和:1+2+3+4+...+n的间接递归函数实现。
//直接递归函数的实现:
//long sum(int n)
//{
//if(n==1) return(1);//递推结束条件
//return(sum(n-1)+n);//递推过程
//}
//将函数sum()改为两个函数实现间接递归计算和
#include<stdio.h>
long add(int);
long acc(int);
long acc(int n)
{
if(n==1) return 1;
return (add(n));
}
long add(int n)
{
return(acc(n-1)+n);
}
void main(void)
{
int n;
printf("Enter n:");
scanf("%d",&n);
printf("The sum is %ld\n", acc(n) );
}
5、
//编写一个程序求满足1*1+2*2+3*3+…+n*n<1000的最大的n(要求用递归函数实现)
#include<iostream.h>
int findn(int,int);
void main()
{
cout<<"n="<<findn(0,0)<<endl;
}
int findn(int n,int s)
{
int s1,n1;
s1=s+n*n;
if(s1<1000){
n1=n+1;
return findn(n1,s1);
}
else
return n-1;
}
6、
/* 递归函数例6.c
采用递归方法计算x的n次方
*/
#include<stdio.h>
double fun(double x,int n)
{
if(n==0) return 1.0;
return x*fun(x,n-1);
}
void main(void)
{
double y;int n;
printf("input y and n:");
scanf("%lf%d",&y,&n);
printf("the result is %lf",fun(y,n));
}
7、
// 递归函数例--正整数的逆向输出.cpp
#include<stdio.h>
void Reverse_display(unsigned int n)
{
if(n/10==0){
printf("%d",n);
return;
}
else{
printf("%d",n%10);
Reverse_display(n/10);
}
}
void main(void)
{
unsigned n;
printf("Enter a positive unsinged integer:");
scanf("%d",&n);
Reverse_display(n);
}
8、
//递归函数例子.cpp
//编写递归函数完成以下公式的计算:
//sum(n)=1-1/2+1/3-1/4+... (其中n>0)
#include<iostream.h>
double Fun(int n)
{
if(n==1)
return 1;
else
if(n%2==0)
return Fun(n-1)-1.0/n;
else
return Fun(n-1)+1.0/n;
}
void main(void)
{
int n;
cout<<"input n:";
cin>>n;
cout<<"result="<<Fun(n)<<endl;
}
9、
//递归求满足不等式的n值.cpp
#include<iostream>
using namespace std;
int fun(int s,int n)
{
n++;
s+=n*n;
if (s>1000)
return n-1;
else return fun(s,n);
}
void main(void)
{
cout<<fun(0,0)<<endl;
}
再看一个自认为不错的别人的解释:
#include <iostream>
using namespace std;
int main()
{
void Test(int);
Test(1);
return 0;
}
void Test(int n)
{
cout<<n<<endl;
if(n < 3)
{
Test( n + 1 );
cout<<n<<endl;
}
}
输出结果为
1
2
3
2
1
那么在这段代码中if()前面的输出流为头代码,中间的Test( n + 1 )为递归表达式,这里的尾代码依然是一个输出流
那么分析此程序怎么做呢?很简单,八个字
“头尾分开,等待归来”
头尾分开,就是将两个cout<<n<<endl分开,第一个cout<<n<<endl执行,然后转入第一次递归,等待递归结束后回到第二个cout<<n<<endl语句执行
这样说很抽象,我们一步步分析一下
第一次调用,n=1
执行头cout<<n<<endl,输出1,并且尾cout<<n<<endl等待,其值也是1,但未输出;
进入第一次递归,n=2
执行头cout<<n<<endl,输出2,并且尾cout<<n<<endl等待,其值是2,但未输出;
进入第二次递归,n=3
执行头cout<<n<<endl,输出3,但判断n < 3 不成立,即不再执行尾cout<<n<<endl语句,函数体结束
回到第一次递归体,执行等待的尾cout<<n<<endl,输出2,第一次递归体结束,会带最外层
执行等待的cout<<n<<endl,输出1,整个函数调用结束,回到main()函数体继续执行其他命令.
形象的说就像是一架手风琴一样,函数调用开始就拉开手风琴,然后进入递归,等待内层递归结束才执行后面的代码
也就八个字“头尾分开,等待归来”
其实这就是实现的栈的结构
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
看一个解释例子:
把一个整形数各个位的数字正向输出,比如n=45789,输出的顺序为4,5,7,8,9。
#include "iostream.h"
void rev(int n);
void main()
{
int n=45789;
rev(n);
}
void rev(int n)
{
if(n/10!=0)
rev(n/10);//递归代码
cout<<n%10<<endl;//尾代码在每次都是要执行的,
}
rev(45789)时:
n/10!=0成立,
执行rev(4578);
cout<<45789%10<<endl;先“忍着”--忍1
rev(4578)时:
n/10!=0成立,
执行rev(457);
cout<<4578%10<<endl;先“忍着”--忍2
rev(457)时:
n/10!=0成立,
执行rev(45);
cout<<457%10<<endl;先“忍着”--忍3
rev(45)时:
n/10!=0成立,
执行rev(4);
cout<<45%10<<endl;先“忍着”--忍4
rev(4)时:
直接执行cout<<4%10<<endl;
开始回溯----->>最里面的先执行,逐渐向外延伸。。。
忍4----->>忍3----->>忍2----->>忍1
在这里好像和栈的压入相仿,但是不只是压入数据这样简单,应该是压入的是代码“cout<<n%10<<endl;”对,压入的就是这句!!
递归三个注意:
首代码 {每次递归都要执行,一般限定递归的结束}
递归代码{递归的核心}
尾代码 {代码入栈}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
再看一个例子:
void IntToString(int n,char *s,int &zero) 注意这里的引用
{
if(n/10==0)
{
s[zero++]=n+'0';
}
else
{
IntToString(n/10,s,zero);
s[zero++]=n%10+'0';
}
}
假设输入的是n=1234
过程如下:
1234/10!=0
执行IntToString(1234/10,s,zero)注意这里不是真正的执行,zero不能代入数据
s[zero++]=1234%10等待1
123/10!=0
执行IntToString(123/10,s,zero)
s[zero++]=123%10等待2
12/10!=0
执行IntToString(12/10,s,zero)
s[zero++]=12%10等待3
1/10==0
先执行s[zero++]=1+'0';从这时开始zero 才有了真正数据,不再是一种数据表示,也就是s[0]='1';zero+=1;
回逆:
方向是逆的;;;;
s[zero++]=12%10等待3 s[1]='2';zero+=1;
s[zero++]=123%10等待2 s[2]='3';zero+=1;
s[zero++]=1234%10等待1 s[3]='4';zero+=1;
执行完毕!