C和指针 第七章 函数递归与迭代

C语言通过运行时堆栈支持递归函数的实现,递归函数时直接或者间接调用自身的函数,经常有人拿斐波那契实现当做递归的实现,然后这样做效率并不高。

n < 1;  Fib(1) =1

n = 2;  Fib(2) = 1

n > 2; Fib(n) = Fib(n - 1) + Fib(n - 2); 

由于每个递归调用都会触发另外两个递归调用,而这两个调用还将继续触发下去,这样会有大量的冗余计算。例如:计算Fib(10)过程,Fib(3)被计算了21次;

#include <stdio.h>

int fib(n)
{
	static count = 0;
	if (n <= 2)
		return 1;
	if (n == 3) {
		count++;
		printf("调用fib(3) %d 次\n", count);
	}
	return fib(n - 1) + fib(n - 2);
}

int main()
{
	printf("%d", fib(10));

	while (1)
		;
	return 0;
}

调用21次:

除了一次调用之外其他的全部是多余的计算,由于函数是尾递归,所以可以方便的转换为迭代循环来实现

下面通过迭代的方法来实现

long fib(int n)
{
	long result;
	long previous_result;
	long previous_older_result;

	result = previous_result = 1;
	while (n > 2) {
		n -= 1;
		previous_result = result;
		previous_older_result = previous_result;
		result = previous_result + previous_older_result;
	}
	return result;
}

递归带来的好处是可读性,但不正确的使用也会使开销也会增大。

下面是一个利用递归把整数转换成字符形式,如4321转换成'4','3', '2', '1'。

void num_to_char(int num)
{
	int quotient;
	
	quotient = num / 10;
	if (quotient != 0) {
		num_to_char(quotient);
	}
	printf("%c", num % 10 + '0');
}

递归函数每次执行时必须越来越接近出口,这里的出口就是 quotient 为 0时。

 

posted @ 2016-08-17 23:26  xnuwu  阅读(373)  评论(0编辑  收藏  举报