Hello everyone 我是Bladcub~
欢迎再次来到我的“一周一篇小博客“的专题栏目
-----我刚学习了函数递归 ,一开始也很是不懂 然后练习了很多题后 有所感悟, 在此和大家分享交流学习!!! 若有不妥的地方请大神指点一二 !!!万分感谢!!!
划重点:此次内容较长 !
第一步 了解函数递归
-
递归的定义:
一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的。用递归过程定义的函数,称为递归函数,例如连加、连乘及阶乘等。凡是递归的函数,都是可计算的,即能行的 。(来自百度百科) -
递归是什么?
用编程技巧通常把一个大型复 杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,用少量的程序描述出复杂的解题过程,减少程序的代码量。 -
递归的两个必要条件
—存在限制条件,当满足这个限制条件的时候,递归便不再继续。
—每次递归调用之后越来越接近这个限制条件
第二步 直接上代码感受(建议练习)
- 递归方式实现打印一个整数的每一位
#include<stdio.h>
void recur(int n)
{
if (n / 10 == 0)
{
printf("%d ", n);
}
else
{
recur(n / 10);
printf("%d ", n%10);
}
}
int main()
{
int n = 0;
printf("请输入你要打印的整数:");
scanf("%d", &n);
recur(n);
return 0;
}
- 实现求n的阶乘(不考虑溢出的问题)
首先是递归方法:
#include<stdio.h>
int fac(int n)
{
if (n < 2)
{
return 1;
}
else
{
n = n*fac(n - 1);
return n;
}
}
int main()
{
int n = 0;
printf("请输入你的数字:\n");
scanf("%d", &n);
fac(n);
printf("他的阶乘为:%d\n", fac(n));
return 0;
}
然后放一个非递归方法 大家感受一下不同:
#include<stdio.h>
int fac(int N)
{
int ret = 1;
for (int i = 2; i <= N; i++)
{
ret *= i;
}
return ret;
}
int main()
{
int n = 0;
printf("请输入你的数字:\n");
scanf("%d", &n);
fac(n);
printf("他的阶乘为:%d\n",fac(n));
return 0;
}
- 求字符串长度
递归:
#include<stdio.h>
int my_strlen(char *arr)
{
if (*arr != '\0')
{
return 1 + my_strlen(arr + 1);
}
else
{
return 0;
}
}
int main()
{
char arr[] = "hello world";
my_strlen(arr);
printf("字符串的长度为:%d\n", my_strlen(arr));
}
非递归:
#include<stdio.h>
int my_strlen(char *arr)
{
int count = 0;
while(*arr != '\0')
{
arr++;
count++;
}
return count;
}
int main()
{
char arr[] = "hello world";
my_strlen(arr);
printf("字符串的长度为:%d\n", my_strlen(arr));
}
- 编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
#include<stdio.h>
void reverse_string(char * string)
{
if (*string != '\0')
{
reverse_string(string + 1);
}
else
{
printf("%c", *string);
}
printf("%c", *string);
}
int main()
{
char *string = "abcdef";
reverse_string(string);
return 0;
}
- 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
例如,调用DigitSum(1234),则应该返回1+2+3+4,它的和是10
输入:1234,输出:10
#include<stdio.h>
int DigitSum(int n)
{
if (n <10)
{
return n;
}
else
{
return n % 10 + DigitSum(n / 10);
}
}
int main()
{
int n = 0;
printf("请输入你的数字:\n");
scanf("%d", &n);
DigitSum(n);
printf("其返回值为:%d\n",DigitSum(n));
return 0;
}
- 编写一个函数实现n的k次方,使用递归实现。
#include<stdio.h>
int biqu(int n,int k)
{
if (k <= 0)
return 1;
else
return n*biqu(n, k - 1);
}
int main()
{
int n = 0;
int k = 0;
printf("请输入你的数字:\n");
scanf("%d", &n);
printf("次方数:\n");
scanf("%d", &k);
biqu(n,k);
printf("其k次方结果为:%d\n", biqu(n,k));
return 0;
}
- 计算斐波那契数
递归:
#include<stdio.h>
int fibo(int n)
{
if (n <=2)
{
return 1;
}
else
{
return fibo(n - 1) + fibo(n - 2);
}
}
int main()
{
int n = 0;
printf("你输入的数");
scanf("%d", &n);
fibo(n);
printf("斐波那契值为:%d\n", fibo(n));
return 0;
}
非递归:
#include<stdio.h>
int fibo(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
printf("你输入的数");
scanf("%d", &n);
fibo(n);
printf("斐波那契值为:%d\n", fibo(n));
return 0;
}
不知道你细细的看完这些代码,或者自己实际编写之后有没有感觉 递归就像是无限月读 ps:哈哈哈哈资深火影迷, 如果有些代码不是很明白可以在纸上面写出他的过程, 慢慢计算感受。 刚开始我也是这样子的,在这里说一下我的感受: 一层一层的套进去,然后再一层层的反着再出来。 哈哈哈也不知道这种感受对不对
第三步 更加深入的感受
汉诺塔问题求解:
1.汉诺塔游戏规则:每次只能移动一个盘子,并且大的盘子不能在小的盘子上面
2.解题步骤:
第一步:
把n-1个模块 从塔1移动到塔2
把第n个模块 从塔1移动到塔3
第二步:
把n-1个模块 从塔2移动到塔3
3.其原理:
要解决n层的汉诺塔
就必须解决n-1层的汉诺塔
…
必须解决第1层汉诺塔
#include<stdio.h>
int i = 1;//步数
void move(int n, char a, char c)//显示移动路径
{
printf("第%d步 : 把第%d个盘子从%c--->移动到%c\n", i++, n, a, c);
}
void Hanoi(int n, char a, char b, char c)//递归算法
{
if (n == 1) move(n, a, c); //如果只有一个盘子那么直接从A柱移到C柱
else
{
Hanoi(n - 1, a, c, b); //把A柱n-1个盘子移到B柱
move(n, a, c); //把最后一个盘子从A柱移到C柱
Hanoi(n - 1, b, a, c); //把B柱n-1个盘子移到C柱
}
}
int main()
{
int m;
scanf("%d", &m);//输入盘子的个数
Hanoi(m, 'A', 'B', 'C');
return 0;
}
第四步 总结心得
身为小白的我还需要多加练习!自己还有许多不懂的地方要多加深入研究,可能此次总结并不是很完美,我以后会多加学习进步的!