zoukankan      html  css  js  c++  java
  • 数据结构第九篇——栈与递归

    栈还有一个重要应用是在程序设计中实现递归。递归是计算机 科学和数学中一种解决问题的及其重要的方法。在数据结构中,可以用它来设计简单。易于理解的算法,特别是在一些具有递归定义的结构上设计算法。

    递归的概念

    一个直接或间接地调用自己的函数,称作递归函数。递归是程序设计中一个强有力的方法。

    递归函数和运行时栈

    栈还有一个重要应用就是在程序设计语言中实现函数调用。当一个函数在运行期间调用另一个函数时,在运行被调用函数之前,系统需要将实际参数和返回值地址等数据传递给被调函数,当函数调用时,这些数据与局部变量一起构成一条“工作记录”,被压入系统提供的栈。

    下面用一个简单的阶乘函数的执行过程来说明递归与栈的关系。描述如下:

    1 int fact(int w)
    2 {
    3     if(w==0)
    4     return 1;
    5     else
    6     t=fact(w-1)
    7     return (w*t);
    8 } 

    递归算法的设计方法

    递归时解决复杂问题的一种有效方法。如果掌握了递归算法的设计思路,就能比较容易地解决一类复杂的问题。但是什么样的问题可以用递归来解决呢?如何设计递归算法呢?

    一般来说,如果一个复杂的问题能够被分解成若干个同类型的子问题,那么这个问题可以用递归算法实现。

    在设计递归算法时,应该遵循下面的规则:

    ①定义一个最小规模的问题,并给出其解。

    ②把复杂的问题划分为同类型的若干规模较小的子问题 ,并分别解决子问题。

    ③把各子问题旳解组合起来,即可得到原问题的解。

    例如:汉诺塔问题:

    1 void Hanoi(int n,char A,char B,char C)
    2 {
    3     if(n>0)                //n=0是最小子问题,不做任何动作,直接退出 
    4     {
    5         Hanoi(n-1,A,C,B);    //子问题①:将A上面的n-1个盘子移到B上 
    6         Move(A,n.C);        //将编号为n的圆盘从A移到C 
    7         Hanoi(n-1,B,A,C);    //子问题②:将B上的n-1个盘子移到C上 
    8     }
    9 }

    递归算法的分析
    利用递归使我们设计算法和编程都非常简单,可读性高。但是往往导致算法效率比较低。

    这体现了算法的简单性与效率之间的矛盾。

    用Fibonacci数列来说明这个问题。

    1 long Fib(int n)
    2 {
    3     if(n==1||n==2)
    4     return 1;
    5     else
    6     return Fib(n-1)+Fib(n-2);
    7 } 

    从调用情况来看,相同实参的同一个函数被调用了多次。求Fib(6)时,Fib(3)被调用了3次,Fib(2)被调用了5次,总共调用的次数为15次。算法时间复杂度为O(2n)。
    为了便于比较,下面给出非递归算法解决Fibonacci问题。

     1 long FibIter(int n)
     2 {
     3     long oneback,twoback,current;
     4     oneback=1;
     5     twoback=1;
     6     
     7     if(n==1||n==2)
     8     return 1;
     9     else
    10     {
    11         for(int i=0;i<n;i++)
    12         {
    13             current=oneback+twoback;
    14             twoback=oneback;
    15             oneback=current;
    16         }
    17     }
    18     return current;
    19 }

    很显然,以上算法当n>=3时,时间复杂度是n-2,远小于递归算法的时间复杂度。

    需要注意的是,在使用递归时必须权衡设计简单与算法的时间和空间复杂度的关系,再有足够并且效率要求不高的情况下可以使用递归。

  • 相关阅读:
    R语言 主成分分析
    主成分分析(PCA)及其在R里的实现
    UML类图几种关系的总结
    微信Android客户端架构演进之路
    Android单元测试实践
    Android studio 快捷键(Mac)
    Android 启动模式及常用的Intent的Flag
    linux常用命令 (mac ),积少成多
    Android Studio IDE 简单学习和介绍
    轻量级分布式 RPC 框架
  • 原文地址:https://www.cnblogs.com/tenjl-exv/p/7575561.html
Copyright © 2011-2022 走看看