• (转)(c#)数据结构与算法分析 递归


     

    递归
        不知道有新手听没听过别人拿剥糖块来形容递归,诸如一层层地剥好比一层层地进入递归。这种比喻可是误导了我,只想着剥了,其实剥完皮儿,取出糖块,再把皮儿一层层地穿上才算个完整的递归。    

        递归就是自己调用自己的函数或方法了,一般情况,像我这样的新手刚接触递归的时候,迷就迷在了不明白递归的原理上,在 (c#)数据结构与算法分析 --栈与队列 中说过,编译器一般用栈来实现递归,具体就看那篇文章吧。

        这里先举一个用到递归的例子。

        求第n项的三角数字,三角数字就是数列中,第n项的值是第n-1项加上n得来的。这里可不是那个斐波那契数列。
        1,3,6,10,15,21......... 这些个数就是三角数字。

        这个递归方法就是计算第n项的三角数字:
     1 //使用递归求第n项的三角数
     2 private int triangle(int n)
     3         {
     4             if (n == 1//这是递归的基准情形,一个递归没有基准的话,就没法跳出递归。
     5             {
     6                 return n;
     7             }
     8             else
     9             {
    10                 return (n + triangle(n - 1)); //调用本方法
    11             }
    12         }

    很简单的一个算法,可用 第n个三角数字=(n*n+n)/2 这个公式来验证其正确性。

    仔细看看这个图就会完全明白递归到底怎么递归了。

    n=5时,开始调用

    第1层

    n=5

    第2层

    n=4

    第3层

    n=3

    第4层

    n=2

    第3层

    n=1

    返回 1
    加 2
    返回 3
    加 3
    返回 6
    加 4
    返回 10
    加 5
    返回 15


    返回15
    (这个表格在firefox下显示有点问题)


        这时,应该把递归理顺了吧,自己可以试试用递归求阶乘,然后试着解决汉诺塔问题,google搜一下会有很多汉诺塔问题的源码。

        很明显,上面那个递归是尾递归,在某些情况下,比如函数体比较庞大,有很多局部变量,则很容易引起栈溢出。有时候应该消除递归。
       
        这就用到栈了,下面这个源码,功能和上面一样,只不过用栈来消除递归了。
     1 //消除递归,使用栈代替递归
     2         private int triangleStack(int n)
     3         {
     4             Stack<int> traingle = new Stack<int>(); //这个栈来模拟递归中的环境变量
     5 
     6             while (n >= 1//相当于递归中的基准了
     7             {
     8                 traingle.Push(n); //将每次递减的值压入栈,相当于逐层调用递归
     9                 n = n - 1;
    10             }
    11 
    12             while (traingle.Count > 0//这个相当于逐层跳出递归
    13             {
    14                 n = n + traingle.Pop(); //计算
    15             }
    16 
    17             return n;
    18         }

        不是很难吧,主要把递归的原理理清,思路自然就明了了。

        要注意的是,使用递归千万可别忘了基准情形,不然就永远递归不出来了。递归的效率有时候比较低,这样就可以用栈或循环来代替递归了。

    版权说明:作者:张颖希PocketZ's Blog
    出处:http://www.cnblogs.com/PocketZ
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    若本文为翻译内容,目的为练习英文水平,如有雷同,纯属意外!有不妥之处,欢迎拍砖

  • 相关阅读:
    Intersecting Lines (计算几何基础+判断两直线的位置关系)
    Morley's Theorem (计算几何基础+向量点积、叉积、旋转、夹角等+两直线的交点)
    TOYS(计算几何基础+点与直线的位置关系)
    Berland National Library
    PAT L2-017. 人以群分
    6.9服务与主机之间的映射
    第六章 部署
    5.12.1再试一次
    第5章 分解单块系统
    4.14.6 —种混合方式
  • 原文地址:https://www.cnblogs.com/PocketZ/p/1711989.html
Copyright © 2020-2023  润新知