0
点赞
收藏
分享

微信扫一扫

C语言P3外传函数递归训练

朱小落 2022-04-25 阅读 58

函数的递归

文章目录

什么是递归

递归的主要思想

递归的两个必要条件

递归与迭代的关系与选择

递归与迭代共同解斐波那契数列

//递归法求斐波那契数列
#include<stdio.h>

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

int main()
{
	int n = 0;
	scanf("%d", &n);
	int fibnum = Fib(n);
	printf("%d", fibnum);
	return 0;
}

要注意,在不考虑溢出的情况下我们计算第40个斐波那契数列,程序就需要等待好一会才能计算完毕,这效率显然不行,我们下面来看迭代法。

//迭代法求斐波那契数列
#include<stdio.h>

int main()
{
	int n = 0;
	int a = 1;
	int b = 1;
	int c = 1;
	scanf("%d", &n);
	if (n == 0)
	{
		printf("0\n");
	}
	else if (n <= 2)
	{
		printf("%d", c);
	}
	else 
	{
		while (n>2)
		{
			c = a + b;
			a = b;
			b = c;
			n--;
		}
		printf("%d", c);
	}
	return 0;
}

递归相关练习题

1.不创建临时变量求出字符串长度

上代码:

//递归求字符串长度
#include<stdio.h>

int my_strlen(char* str)
{
	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}

int main()
{
	char arr[] = "Hello KissKernel!!!";
	int num = my_strlen(arr);

	printf("%d", num);

	return 0;
}

2.递归实现n的阶乘

//递归实现n的阶乘
#include<stdio.h>

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

int main()
{
	int n = 0;
	scanf("%d", &n);
	int facnum = Fac(n);
	printf("%d\n", facnum);

	return 0;
}

3.递归实现逆序字符串

//递归实现逆序字符串
#include<stdio.h>
#include<string.h>
void reverse(char* first)
{
	int sz = strlen(first);
	static int n = 1;
	char* end = first + sz - n;
	if (first < end)
	{
		n++;
		reverse(first + 1);
	}
	char tmp = *first;
	*first = *end;
	*end = tmp;
}

int main()
{
	char arr[] = "Hello KissKernel!!!";
	printf("%s\n", arr);//逆序前
	reverse(arr);
	printf("%s\n", arr);//逆序后
	return 0;
}

这里设置的静态n是为了记录尾指针向前移动的数据,当然还有一种方法是进入函数直接逆序,将头字符保存起来,将尾字符置为’\0’,递归结束后在将头字符赋给尾字符;
代码如下:

//递归实现逆序字符串
#include<stdio.h>
#include<string.h>
void reverse(char* first)
{
	int sz = strlen(first);
	char* end = first + sz - 1;
	char tmp = *first;
	*first = *end;
	*end = '\0';
	if (*(first + 1) != '\0')
	{
		reverse(first + 1);
	}
	*end = tmp;
}

int main()
{
	char arr[] = "Hello KissKernel!!!";
	printf("%s\n", arr);//逆序前
	reverse(arr);
	printf("%s\n", arr);//逆序后
	return 0;
}

4.递归实现n的k次方(有优化版本已更新)

#include<stdio.h>

int Sqr2(int n, int k)
{
	if (k == 0)
	{
		return 1;
	}
	else
	{
		return n * Sqr2(n, k - 1);
	}


}
int Sqr(int n, int k)
{
	if (k == 0)
	{
		return 1;
	}
	else if(k%2 == 0)
	{
		return Sqr(n,k/2) * Sqr(n, k /2);
	}
	else
	{
		return n * Sqr(n, k - 1);
	}



}

int main()
{
	int n = 0;
	int k = 0;
	scanf("%d %d", &n, &k);
	int ret = Sqr(n, k);
	printf("%d\n", ret);
	return 0;
}

优化方法,如果求得k次方为偶数,既可以转化为两个n的k/2次方的乘积;可以将时间复杂度从O(n)降低到O(logn)

5.青蛙跳台阶问题

//青蛙跳台阶问题
#include<stdio.h>

int Fun(int n)
{
	if (n > 2)
	{
		return Fun(n - 1) + Fun(n - 2);
	}
	else
		return n;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int num = Fun(n);
	printf("%d", num);
	return 0;
}

6.汉诺塔问题

//汉诺塔问题

#include<stdio.h>

int move = 0;

void Move(char n1, char n2)
{
	move++;
}

void Fmove(int n, char a, char b, char c)//将a上的圆盘借助从b移动到c
{
	if (n == 1)
	{
		Move(a, c);
	}
	else
	{
		Fmove(n - 1, a, c, b);//将a上的n-1个圆盘借助c移动到b;
		Move(a, c);//将a上的圆盘放到c上;
		Fmove(n - 1, b, a, c);//将b上的n-1个圆盘借助a移动到c上。至此移动结束
	}
}

int main()
{
	int n = 0;
	char a = 'A';
	char b = 'B';
	char c = 'C';
	scanf("%d", &n);
	Fmove(n, a, b, c);
	printf("%d\n", move);

	return 0;
}
举报

相关推荐

0 条评论