c语言经典-递归

说到递归,相信大家都不陌生,采用递归可以解决一些重复性,相似性高的东西。今天我就介绍一些经典递归问题

斐波那契数列

#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,这都是换汤不换药。寻找规律就会发现就是斐波那契数列,从而解决问题!
就分享到这了,谢谢大家!,点个赞呗,么么哒!

发布了25 篇原创文章 · 获赞 16 · 访问量 930

猜你喜欢

转载自blog.csdn.net/weixin_44024891/article/details/90514281