【算法】计算机科学的精髓——递归

【一】递归定义与延伸

先给出递归的定义

递归算法是一种直接或者间接调用自身函数或者方法的算法。

递归是计算机科学的精髓,这一点在吴军老师的《Google方法论》专栏也有同样的阐述,他认为递归是计算机思维和人思维最大的不同。

我们常用的正向思维成为递推,而递归可以说是一种逆向思维。举例来说,计算一个数的阶乘,比如5 !,我们惯用的递推思维一定是 1x2x3x4x5 ,那么计算机的递归思想会如何计算呢?正好与人类相反,比如5 !,它会把5 !拆分成5x4 !,再把4 !拆分成 4x3 !,直到1 !=1 ,也就是达到了终止条件;接下来要做的,就是倒推回所有的结果。所以总结来说,递归的过程是 自顶向下设计,自下而上回归

那么计算机为什么要采用这种与人类思维完全相反的方式呢?

因为算法逻辑非常简单。递归过程的每一步用的都是同一个算法,计算机要做的,就是自顶向下不断重复。

递归方法具有如下的特点,为了便于记忆,我把它总结为 可分解,自重复,有出口

  1. 可分解:一个问题的解可以分解为几个子问题的解
  2. 自重复:这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
  3. 有出口:存在递归终止条件

其实归纳来说,递归的本质有两条:自顶而下,自己不断重复。

【二】递归代码如何写

说了这么半天大道理,那么我们如何写递归代码呢?

  1. 找到将大问题分解为小问题的规律
  2. 基于规律写出递推公式
  3. 推敲终止条件
  4. 将递推公式和终止条件翻译成代码

写递归代码的注意事项:

  1. 避免堆栈溢出
  2. 避免重复计算

【三】递归的应用场景

  1. 斐波那契数列

    F(1)=1,F(2)=1,F(n) = F(n-1) + F(n-2)(n>=3,n∈N*)

    public class FibonacciSequence {
        public static void main(String[] args){
            System.out.println(Fribonacci(9));
        }
        public static int Fribonacci(int n){
            if(n <= 2)
                return 1;
            else
                return Fribonacci(n-1)+Fribonacci(n-2);
        }
    }
    
  2. 前中后序二叉树遍历

    	/**
    	 * 递归前序遍历
    	 */
    	public static void ProOrder(TreeNode tree) {
    		System.out.println(tree.value);
    		if (tree.left != null) {
    			ProOrder(tree.left);
    		}
    		if (tree.right != null) {
    			ProOrder(tree.right);
    		}
    	}
     
    	/**
    	 * 递归中序遍历
    	 */
    	public static void InOrder(TreeNode tree) {
     
    		if (tree.left != null) {
    			InOrder(tree.left);
    		}
    		System.out.println(tree.value);
    		if (tree.right != null) {
    			InOrder(tree.right);
    		}
    	}
     
    	/**
    	 * 递归后顺遍历
    	 */
    	public static void PostOrder(TreeNode tree) {
     
    		if (tree.left != null) {
    			PostOrder(tree.left);
    		}
     
    		if (tree.right != null) {
    			PostOrder(tree.right);
    		}
    		System.out.println(tree.value);
    	}
     
    
  3. 汉诺塔问题

  4. DFS深度优先搜索

  5. N皇后问题

【四】总结思考

其实从递归的思想中,我们可以受到启发:

人类的认识受到我们生活空间的局限,因此习惯于从小到大渐渐扩展的思维方式。而计算机因为可以直接处理大场景,因此有时会采用从大到小,层层分解的递归方法。这可以说给我们提供了一个新的看问题的方法和解决问题的思路。

发布了23 篇原创文章 · 获赞 3 · 访问量 1838

猜你喜欢

转载自blog.csdn.net/HoyingHan/article/details/104243905
今日推荐