函数递归

一、函数递归

          递归是在程序执行过程中,直接或间接地调用函数自身的过程。通常是要把一个复杂的大规模问题转化成一个个小的问题来求解。递归求解问题在在一些时候可以大大减少代码的复杂程度,增加代码的可读性。

值得注意的是:递归的使用要在每进行一次递归后,问题的规模都要变小;同时递归一定要有递归出口(也就是说,当进行递归到一定程度时,无需在进行递归,直接返回,避免无休止的递归下去)。

//输入一个数字,把它的每一位转化成字符型,并打印(1234->1 2 3 4)
void print(int num)
{
	if (num < 10)
	{
		printf("%c ", num + '0');
		return;
	}
	print(num / 10);
	printf("%c ", num % 10 + '0');
	return;
}
int main()
{
	int num = 1234;
	print(num);
	system("pause");
	return;

}

分析:


//编写函数,不创建临时变量,计算字符串长度
int mystrlen(const char* str)
{
	if (*str == '\0')
		return 0;
	return 1 + mystrlen(str + 1);
}

二、递归与迭代

凡是能通过递归实现的程序,通常可以通过循环转换成迭代形式的。

//eg:编写函数,实现n的阶乘
//递归版本
int factorial(int n)
{
	if (n <= 1)
		return 1;
	return n*factorial(n - 1);
}
//非递归版本
int factorial2(int n)
{
	int sum = 1;
	while (n > 1)
	{
		sum *= n;
		n--;
	}
	return sum;
}
递归函数确实能大大减少代码的长度,增加代码的可读性,可是这是一个不断创建栈桢和释放栈桢的过程,性能会大大降低。这个时候可以用循环改写函数,用迭代版本会大大提高程序运行的效率。
//求第n个斐波那契数
//递归版本
int fib(int n)
{
	if (n <= 2)
		return 1;
	return fib(n - 1) + fib(n - 2);
}
//非递归版本
int fib2(int n)
{
	int pre = 1;
	int ppre = 1;
	int cur = 1;
	while (n > 2)
	{
		cur = pre + ppre;
		ppre = pre;
		pre = cur;
		n--;
	}
	return cur;
}

测试一下上述代码递归和非递归版本计算第30个Fib数所花的时间。

int main()
{
	//递归时间
	int beg = GetTickCount();
	for (int i = 100; i > 0; i--)
	{
		fib(30);
	}
	int end = GetTickCount();
	printf("time1:%d\n", end - beg);
	//非递归时间
	int beg2 = GetTickCount();
	for (int i = 100; i > 0; i--)
	{
		fib2(30);
	}
	int end2 = GetTickCount();
	printf("time2:%d\n", end2 - beg2);
	system("pause");
	return;
}

结果显示,迭代版本明显要比递归版本效率高的多。


并且,当输入的数字特别大,或者递归没有出口,就意味着要不停的建立函数栈桢,但是我们的栈空间是有限的,一旦空间不够用了,就会出现栈溢出。

但也不是不能用递归的方式解决问题,若是问题的规模非常大,难以用不同的方法解决,这是递归的间接性就弥补了它所带来的开销问题。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值