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;

执行完毕!

 

 

 

posted @ 2012-12-16 20:49  deeeeeed  阅读(546)  评论(0编辑  收藏  举报

pppppppppppppp