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

时间:2023-03-08 17:49:21
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次:

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

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

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

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时。