递归

递归的原理及用法

小贴士:

'0'+0='0';
'0'+1='1';

C允许函数调用它本身,这种调用的过程称为递归。

在很多书看到的递归都是求阶乘,还有斐波那切。

这里写一个可以将一个整数打印成字符的函数。

 void binary_to_asii(unsigned int value)
 {
     unsigned int quotient;
     quotient=value/10;
     if(quotient!=0)
        brnary_to_asii(quotient);
    putchar(value%10+'0')
 }

如果输入4082,那么它会打印出4028
程序是这样执行的:先求出408,不为0,
再进入函数,求得,40,不为0,
再进入函数,求得4,不为0,
再进入求得0。

因为先前执行了四次,与所有调用函数一样,调用完要返回执行调用函数的下一条语句。也就是进入了四次,那么就要返回。

先输出4%10=4,
再40%10=0,
再408%10=8,
再4082%10=2。

所谓递归,就是先递进,再回归,递进是因为每次都要进入调用函数。而回归是因为每个函数都是顺序执行的。

原理

每一次的调用,都将会创建一批变量,它们将覆盖递归函数前一次调用所创建的变量,这个是在堆栈上进行的,可以看作一层一层的叠加。而我们达到了某一个条件时,它将把变量一层一层地销毁,让前一次调用继续执行,直到结束。

重点是调用到一个结束条件后,我们不再继续调用了,进而要顺序执行每一次调用的语句。

用法

  1. 确定目标
  2. 找到结束条件
  3. 找到关系式

例如:

算1到n的和

  1. 算从n到1的和
  2. 当n为1时,返回1
  3. n+sum(n-1)
int sum(int n)
{
    if(n==1)
        return 1;
    return n+sum(n-1);
}
int sum(int n)
{
    int ans=0;
    if(n==1)
        ans=1;
    else
        ans=n+sum(n-1);
    return ans;
}

而这样每次都会创建新的变量,会消耗内存,所以可以用循环的尽量不要用递归。

用递归来算二进制可以很好的理解它

#include 

void dectobin( int n );

int main()
{
    int n;

    scanf("%d", &n);
    dectobin(n);

    return 0;
}
void dectobin( int n )
{
    int ans=0;
    ans=n%2;
    if(n>=2)
        dectobin(n/2);//n为1或0时就开始输出,正好是逆序的
    printf("%d",ans==0?0:1);
    return ;
}

比如我们输入5

dectibin(5)前半段

void dectobin( int n )//n为5
{
    int ans=0;
    ans=n%2;//ans=1
    if(n>=2)//n=5表达式为真
        dectobin(n/2);//n/2=2,进入下面的dectobin(2)函数中
}

dectibin(2)前半段

void dectobin( int n )//n为2
{
    int ans=0;
    ans=n%2;//ans=0
    if(n>=2)//n=2表达式为真
        dectobin(n/2);//n/2=1,进入到下面的dectobin(1)函数中
}

dectibin(1)

void dectobin( int n )//n为1
{
    int ans=0;
    ans=n%2;//ans=1
    if(n>=2)//n=1为假
        dectobin(n/2);
    printf("%d",ans==0?0:1);//输出1
    return ;//返回到dectibin(2)函数中
}

dectibin(2)后半段

    //ans=0
    dectobin(n/2);//得到dectibin(1)的返回
    printf("%d",ans==0?0:1);//输出0
    return ;//返回到dectibin(1)函数中

dectibin(5)后半段

    //ans=1
    dectobin(n/2);//得到dectibin(2)的返回
    printf("%d",ans==0?0:1);//输出1
    return ;//返回到main函数中的dectibin(n)中

可以看出printf先后输出的是101

在数据结构与算法分析(C语言描述)中,这样说

递归绝不能作为简单的for循环的代替物。
四条基本法则

  1. 基准情形。有某些基础情形,不用递归都可以求解。
  2. 不断推进。递归调用必须能够朝着产生基准情形的方向前进。
  3. 设计法则。假设所有的递归调用都能运行。
  4. 合成效益法则(compound interest rule)。在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。

你可能感兴趣的:(C语言知识)