概念
递归是不断调用自身,假设递归自己是一个函数的话,那递归的返回值会当作参数再次传入自身
优点:
化繁为简,减少代码量
缺点:
函数调用层次太深,函数递归调用时,系统要在栈中不断保存函数调用时的线程和产生的变量,递归调用太深,会造成栈溢出,这时递归无法返还 。(补充:堆栈溢出是一种内存错误,指的是程序试图往已经满的堆栈中添加数据,导致数据覆盖了其他内存区域或者程序崩溃的情况。它是常见的编程错误之一,通常发生在递归调用和使用过多本地变量等场景下)
代码实战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 二叉树前序遍历