zoukankan      html  css  js  c++  java
  • 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 次
    ", 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时。

  • 相关阅读:
    将C#文档注释生成.chm帮助文档
    Html5shiv
    C#创建COM组件
    WebBrowser控件使用详解
    iframe跨域
    VMware Workstation 虚拟机暂停后无法启动 出现Exception 0xc0000006 (disk error while paging) has occurred.错误
    Java Timer 定时器的使用
    adf笔记
    JS编码解码
    【Python】Django CSRF问题
  • 原文地址:https://www.cnblogs.com/yangxunwu1992/p/5782351.html
Copyright © 2011-2022 走看看