说到递归,相信大家都不陌生,采用递归可以解决一些重复性,相似性高的东西。今天我就介绍一些经典递归问题
斐波那契数列
#include<stdio.h>
#include<stdlib.h>
int fib(int n)
{
if (n <= 0)//判断错误情况
return 0;
else if (n <= 2)//判断1-2的情况
return 1;
else
{
return fib(n - 1) + fib(n - 2);
}
}
//非递归求法
int fib1(int n)
{
if (n <= 0)//判断错误情况
return 0;
else if (n <= 2)//判断1-2的情况
return 1;
else
{
int i = 1, j = 1, k = 1;
int sum = 0;
for (k = 3; k <= n; k++)
{
sum = i + j;
i = j;
j = sum;
}
return sum;
}
}
int main()
{
//1 1 2 3 5 8 13 21 34 55
int value = 0;
int sum = 0;
printf("请输入>");
scanf_s("%d", &value);
puts("递归求法:");
sum = fib(value);
printf("sum = %d\n", sum);
puts("非递归求法:");
sum = fib1(value);
printf("sum = %d\n", sum);
system("pause");
return 0;
}
斐波那契数列的规律是1 1 2 3 5 8 13 21 34 55,第三项后每一项都是前两项之和,第n项的前n项和等于第n+2项值-1。
对于这样的问题,在编程中我们可以采用for循环和递归,for循环中我们分别用两个变i,j量分别指向1 1,sum = i+j,循环一次我们移项。i =j;
j = sum;就这样循环n-2项就可以求出第n项的值。递归的更为简单,看代码就可以理解。
但是在这里,我提一下,斐波那契数列虽然用递归表达简单,但是它的运行效率比for()低,如果要求的话,采用for()更好,递归仅作为了解。
2、写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和,如1729 1+7+2+9
#include<stdio.h>
#include<stdlib.h>
int DigitSum(int n)
{
if (n)
{
//DigitSum(n / 10);
return n % 10 + DigitSum(n / 10);
}
return 0;
}
int main()
{
int value = 0;
int sum = 0;
printf("请输入一个非负整数>");
scanf_s("%d", &value);
sum = DigitSum(value);
printf("sum = %d\n", sum);
system("pause");
return 0;
}
这个没什么说的,就是递归的基本用法。在递归中,每个递归都有一个共同的特点,就是每次递归都会趋近递归结束条件。
3、 编写一个函数 reverse_string(char * string)(递归实现)
实现:将参数字符串中的字符反向排列。
要求:不能使用C函数库中的字符串操作函数。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int My_strlen(char* s)
{
if (*s != '\0')
{
return 1 + My_strlen(s + 1);
}
return 0;
}
void reverse_string(char * str)
{
int len = mystrlen(str);//获得字符长度,不包括\0
char tmp;
if (*str)
{
tmp = str[0];
str[0] = str[len - 1];
str[len - 1] = 0;
reverse_string(str + 1);
str[len - 1] = tmp;
}
}
int main()
{
char str[20] = "abcdefg";
puts(str);
reverse_string(str);
puts(str);
system("pause");
return 0;
}
这道题应该是递归中特难的了,字符串的逆序,里面的递归在纸上写一下它的递归过程。它的每一步都很精巧,不多不少。这道题希望大家好好品一下,
4、递归方式实现打印一个整数的每一位
#include<stdio.h>
#include<stdlib.h>
void Print(int n)
{
//1729
//(172) 9
//(17) 2 9
//(1) 7 2 9
if(n > 9)
{
Print(n / 10);
}
printf("%d ",n % 10);
}
int main()
{
int value = 0;
printf("请输入>");
scanf_s("%d", &value);
Print(value);
system("pause");
return 0;
}
这道题采用递归最完美不过了,1729求每位数从后往前容易,从前往后就不容易了。值得品味!
5、编写一个函数实现n^k,使用递归实现
#include<stdio.h>
#include<stdlib.h>
double Calculate_power(int value, int power)
{
//power位为传递进来的次方,有三种情况- 0 +
if (power < 0)
{
if (power == -1)
return 1.0 / value;
return 1.0 / value * Calculate_power(value, power + 1);
}
else if (power == 0)
{
return 0.0;
}
else
{
if (power == 1)
return value * 1.0;
return 1.0 * value * Calculate_power(value, power - 1);
}
}
int main()
{
int value = 0, power = 0;
double acc_value = 0.0;
printf("请输入您想计算的值和多少次方value、power>");
scanf_s("%d%d", &value, &power);
acc_value = Calculate_power(value, power);
printf("acc_value = %f\n", acc_value);
system("pause");
return 0;
}
我写的这个可以求负数的n次方,大家可以看一下。
汉诺塔
经典汉诺塔问题,往年面试的经典问题之一
#include<stdio.h>
#include<stdlib.h>
int i = 1;//全局变量
void move(int n, char one, char two, char three)
{
if (n == 1)
{
printf("Step%2d \t %c -> %c\n", i++, one, three);
}
else
{
move(n-1, one, three, two);
printf("Step%2d \t %c -> %c\n", i++, one, three);
move(n-1, two, one, three);
}
}
int main()
{
char one = 'A', two = 'B', three = 'C';
int num = 1;
printf("请输入圆盘的个数num>");
scanf_s("%d", &num);
move(num, one, two, three);
system("pause");
return 0;
}
青蛙跳台阶问题(斐波那契数列变种)
这中问题先找每一种情况的种类有多少,锁喉规律就出现了。
#include<stdio.h>
#include<stdlib.h>
int D_jump_floor1(int n)
{
if (1 == n)
return 1;
else if (2 == n)
return 2;
return D_jump_floor1(n - 1) + D_jump_floor1(n - 2);
}
int D_jump_floor2(int n)
{
//这是1-3跳的情况
if (1 == n)
return 1;
else if (2 == n)
return 2;
else if (3 == n)
return 4;
return D_jump_floor2(n - 1) + D_jump_floor2(n - 2) + D_jump_floor2(n - 3);
}
int main()
{
//青蛙一次可以跳1-2个台阶,因此有一下规律
//1 :1,2 :2,3 : 3......由此发现这是斐波那契额数列,先列出来然后总结规律
int num = 0;//台阶数
int sum = 0;
printf("请输入台阶数num>");
scanf_s("%d", &num);
// sum = D_jump_floor1(num);//1-2
sum = D_jump_floor2(num);//1-3
printf("sum = %d\n", sum);
system("pause");
return 0;
}
有的问青蛙一次可以跳1-2,有些问可以跳1-3,这都是换汤不换药。寻找规律就会发现就是斐波那契数列,从而解决问题!
就分享到这了,谢谢大家!,点个赞呗,么么哒!