C语言笔记总结(三)

函数递归

什么是递归

递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。写⼀个史上最简单的C语⾔递归代码:

#include <stdio.h>

int main()
{
 printf("hehe\n");
 main();//main函数中⼜调⽤了main函数 
 return 0;
}

当然这仅仅是演示递归的一种形式,此代码最终会陷入一种死循环。

递归举例

举例1:求n的阶乘

首先我们要知道什么是阶乘:

  • 对于所有非负整数n,n!的定义是:

    n = 0 时,n!= 1;

  • n > 0 时,n! = n×(n−1)!;

这个定义意味着:

  • 0的阶乘是1,即 0!=1。
  • 1的阶乘也是1,即 1!=1。
  • 对于任何大于1的整数n,n的阶乘是n乘以n-1的阶乘,即 n!=n×(n−1)!。

下面代码演示

int Fact(int n)
{
    if(n = 0)
        return 0;
    else
        return n * Fact(n - 1);
}

int main()
{
	int n;
	scanf_s("%d\n", &n);
	int Ret = Fact(n);
	printf("%d\n", Ret);
	return 0;
}

在第一段代码中我们写了一段阶乘函数;在主函数中进行调用。

举例二:顺序打印一个整数的每一位

比如:

输入:1234   输出:1 2 3 4

对此,我们进行分析:

1234%10 —> 4      我们再对 1234/10—>123;这就相当于去掉了4;

以此类推,我们依次可以得到 4 3 2 1

但是这与我们想要的结果是相反的,对此我们可不可以想一个办法解决呢?

void Print(int n)
{
	if (n > 9)
	{
		Print(n / 10);
	}
	printf("%d", n % 10);
}

int main()
{
	int n;
	scanf_s("%d", &n);
	Print(n);
	return 0;
}

当输入1234时,进入Print,1234是>9的,再进入Print,直到最后打印1,打印1之后,再返回到上一个if语句,打印2,以此类推,我们可以不断打印1 2 3 4。

当然并不是都要用递归解决问题。

例如:求第n斐波那契数。

同样我们先了解什么是斐波那契数:

每个数是前两个数的和,数列的前两个数定义为0和1。因此,斐波那契数列的前几项是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

根据我们之前举得例子,对于斐波那契数我们很容易写成递归的形式
 

int Fit(int n)
{
	if (n <= 2)
		return 1;
	else
		return Fit(n - 1) + Fit(n - 2);
}

int main()
{
	int n;
	scanf_s("%d", &n);
	int ret = Fit(n);
	printf("%d\n", ret);
	return 0;
}

但是当我们以这个代码来完成任务的时候,我们会发现当输入的数值较大时,运算时间会较长,效率低,我们可以添加一个count来看看:

int count = 0;
int Fit(int n)
{
	if (n == 3)
		count++;
	if (n <= 2)
		return 1;
	else
		return Fit(n - 1) + Fit(n - 2);
}

int main()
{
	int n;
	scanf_s("%d", &n);
	int ret = Fit(n);
	printf("%d\n", ret);
	printf("count = %d\n", count);
	return 0;
}

当我们输入某个值时,我们便可以看出第三个数被重复计算了多少次

我们可以对此代码进行优化

int Fit(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 Fit(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;
	scanf_s("%d", &n);
	int ret = Fit(n);
	printf("%d\n", ret);
	return 0;
}

拓展

青蛙跳台阶
汉诺塔

关于这两个问题我们直接给出代码

int Func(int n)
{
	if (n == 1)
		return 1;
	if (n == 2)
		return 2;
	else
		return Func(n - 1) + Func(n - 2);
}

int main()
{
	int n = 0;
	scanf_s("%d", &n);
	int Set = Func(n);
	printf("%d", Set);
	return 0;
}

int count = 0;
void Hant(int n, char a, char b, char c)
{
	if (n == 1)
	{
		printf("%c-->%c\n", a, c);
		count++;
	}
	else
	{
		Hant(n - 1, a, c, b);
		printf("%c-->%c\n", a, b);
		count++;
		Hant(n - 1, b, a, c);
		
	}	
}

int main()
{
	int n = 0;
	scanf_s("%d", &n);
	Hant(n, 'A', 'B', 'C' );
	printf("%d", count);
	return 0;

这两个问题也都是使用递归解决的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值