递归函数(代码实操帮你深层次理解)

本文探讨了递归的概念,包括其优点如简化代码和化繁为简,以及可能的缺点如深度递归可能导致栈溢出。通过代码示例展示了阶乘计算、字符串回文判断和二叉树前序遍历的递归实现,同时介绍了调试流程和注意事项。
摘要由CSDN通过智能技术生成

概念

递归是不断调用自身,假设递归自己是一个函数的话,那递归的返回值会当作参数再次传入自身   

优点:

化繁为简,减少代码量

缺点: 

函数调用层次太深,函数递归调用时,系统要在栈中不断保存函数调用时的线程和产生的变量,递归调用太深,会造成栈溢出,这时递归无法返还 。(补充:堆栈溢出是一种内存错误,指的是程序试图往已经满的堆栈中添加数据,导致数据覆盖了其他内存区域或者程序崩溃的情况。它是常见的编程错误之一,通常发生在递归调用和使用过多本地变量等场景下)

代码实战1

//求n的阶乘 n!=n*(n-1)*(n-2)*....3*2*1
// n = n*[(n-1)!];(n-1)! = (n-1)*[(n-2)!];.......3!=3*2!;2!=2*1!;1!=1
#include <stdio.h>
int factorial(int n)
{
    int f;
    if(n == 0 || n == 1)
    {
        return 1;
    }
    f = n * factorial(n-1);
    return f;
}
int main() {
    int n;
    int ret;
    scanf("%d", &n);
    ret = factorial(n);
    printf("%d! = %d\n", n, ret);
}

结果 eg:

3
3! = 6

注意:

函数factarial 中的局部变量n和f,均属于自动变量。
在每一次调用函数factarial时,都要重新给n和f分配内存。
因此,每一次调用中的n和f,都与另一次调用中的n和f相互独立、互不相关

代码调试流程:

// n =3;3!= 6
#include <stdio.h>
int factorial(int n)
{
    int ret;
    if(n == 0 || n == 1)
    {
        printf("%d! = %d\n",n,1);
        return 1;
    }
    ret = n * factorial(n-1);
    printf("%d! = %d\n",n,ret);
    return ret;
}
int main() {
    int n;
    int ret;
    scanf("%d", &n);
    ret = factorial(n);
    printf("========\n");
    printf("%d! = %d\n", n, ret);
}

输出结果:

3
1! = 1
2! = 2
3! = 6
========
3! = 6

factorial调用流程


 

代码实战2

//判断字符串是否是回文
#include <stdio.h>
#include<string.h>
int  j =0;
char array[128];
void reverse(char *p)
{
    if(*p == '\0')
    {
        return ;
    }
    reverse(p+1);
    array[j] = *p;
    j++;
}
int main()
{
    char str[128];
    gets(str);//gets();getchar();
    reverse(str);
    if( strcmp(array,str) == 0)
    {
        printf("this string is a palindrome\n");
    }else
    {
        printf("this string is not a palindrome\n");
    }
}

输出结果:

eg1:

abcdefgfedcba
this string is a palindrome

eg2:

abc
this string is not a palindrome

代码调试流程

#include <stdio.h>
#include<string.h>//strcmp
int i=0, j =0;//i 为调用次数,j 为返回次数
char array[128];
char *reverse(char *p)
{
    if(*p == '\0')
    {
        return '\0';
    }
    i++;
    reverse(p+1);

    array[j] = *p;
    j++;
    printf("%d%c%c",j,*p,array[j-1]);// %s pk %c
    return p;//p最终返回一次,返回字符串首地址
}
int main()
{
    printf("please input a string\n");
    char str[128];
    char *des;
    gets(str);//gets();getchar();
    int l = strlen(str);
    char arr[l];
    int n;//
    des = reverse(str);
    putchar('\n');
    printf("==========\n");
    printf("des = %c\n",*des);
    for(n = 0;n<l;n++)
    {
        printf("des %d = %c\n",n,*des);
        arr[n] = *des;
        des++;
    }
    //reverse("abc");
    for(n = 0;n<l;n++)
    {
        printf("arr[%d]=%c\n",n,arr[n]);
    }
    for(n = 0;n<l;n++)
    {
        printf("array[%d]=%c\n",n,array[n]);
    }
    int num = strcmp(array,str);
    printf("num=%d\n",num);
    if( num == 0)
    {
        printf("this string is a palindrome\n");
    }else
    {
        printf("this string is not a palindrome\n");
    }
}

测试结果

please input a string
abc
1cc2bb3aa
==========
des = a
des 0 = a
des 1 = b
des 2 = c
arr[0]=a
arr[1]=b
arr[2]=c
array[0]=c
array[1]=b
array[2]=a
num=1
this string is not a palindrome

代码实战3  二叉树前序遍历

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sugcoffee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值