美文网首页
递归算法的奥妙

递归算法的奥妙

作者: 英俊的风 | 来源:发表于2020-07-17 01:47 被阅读0次

递归是什么

递归算法是计算机科学中非常重要的一个概念,用于解决很多的计算机科学问题。是一种直接或者间接调用自身函数或者方法的算法,大部分编程语言都支持函数的自调用。引用知乎使用者李继刚对递回的生动解释:

递归:你开启面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以开启它,你推开门,发现里面还有一扇门,你继续开启它。若干次之后,你开启面前的门后,发现只有一间屋子,没有门了。然后,你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙开启了几扇门。

递归的核心思想

递归的核心思想是分而治之,把问题分解成规模缩小的同类问题的子问题来求解的一种策略,我们通常都是从上而下的思维问题,而递归趋势从下往上进行思维,从小问题开始解决,最终解决大问题。

递归的三要素

1.明确递归终止条件

所谓递归其实就是有去有回,应该有一个明确的临界点,一旦到达了这个临界点,就不用继续往下递去而是开始实实在在的归来。换句话说,该临界点就是一种简单情境,可以防止无限递归。

2.给出递归终止时的处理办法

刚刚说到,在递归的临界点存在一种简单情境,在这种简单情境下,应该直接给出问题的解决方案。一般地,在这种情境下,问题的解决方案是直观的、容易的。

3.提取重复的逻辑,缩小问题规模

递归的关键就是找到如何将大问题分解为小问题的规律。与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。A可以分解为若干子问题B、C、D情况,你可以假设子问题B、C、D已经解决,在此基础上思考如何解决问题A。而且,你只需要思考问题A与子问题B、C、D两层之间的关系即可,不需要一层一层往下思考子问题与子子问题,子子问题与子子子问题之间的关系。从程式实现的角度而言,抽象出一个干净利落的重复的逻辑,来使用相同的方式解决子问题。

递归模型
public static long f(int n){

    if(n == 1)  //递归终止条件

    return 1;   // 简单场景

    return n*f(n-1); // 相同重复逻辑,缩小问题规模
 }

递归经典案例解析

1.斐波纳契数列

斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、 ……
在数学上,斐波纳契数列以如下被以递回的方法定义:F0=0,F1=1,Fn=F(n-1) F(n-2)(n>=2, n∈N)。

经典解法:
public class FibonacciSequence {
/**
* @description 经典递归解法
* 
* 斐波那契数列如下:
* 
*  1,1,2,3,5,8,13,21,34,...
* 
* *那么,計算fib(5)時,需要计算1次fib(4),2次fib(3),3次fib(2),呼叫了2次fib(1)*,即:
* 
*  fib(5) = fib(4)   fib(3)
*  
*  fib(4) = fib(3)   fib(2) ;fib(3) = fib(2)   fib(1)
*  
*  fib(3) = fib(2)   fib(1)
*  
* 这里面包含了许多次重复计算,而实际上只需计算fib(4)、fib(3)、fib(2)和fib(1)各一次即可,
* 后面的optimizeFibonacci函式進行了优化,使时间复杂度降到了O(n).
*/
public static int fibonacci(int n) {
if (n == 1 || n == 2) {     // 递归终止条件
return 1;       // 简单场景
}
return fibonacci(n - 1)   fibonacci(n - 2); // 相同重复逻辑,缩小问题规模
}
经典优化算法:
/**     
* @description 對经典算法的优化
* 
* 斐波那契数列如下:
* 
*  1,1,2,3,5,8,13,21,34,...
* 
* 那么,可以这样看:fib(1,1,5) = fib(1,2,4) = fib(2,3,3) = 5
* 
* 也就是说,以1,1开头的斐波那契数列的第五项正是以1,2开头的斐波那契数列的第四项,
* 而以1,2开头的斐波那契数列的第四项也正是以2,3开头的斐波那契数列的第三项,
* 更直接地,我們就可以一步到位:fib(2,3,3) = 2   3 = 5,计算結束。 
* 
* 注意,前兩個引数是数列的开头兩项,第三个引数是想求的以前兩個引数开头的数列的第几項。
* 
    * 时间复杂度:O(n)
* 
* @author rico       
* @param first 数列的第一項
* @param second 数列的第二項
* @param n 目标项
* @return     
*/
public static int optimizeFibonacci(int first, int second, int n) {
if (n > 0) {
if(n == 1){    // 递归终止条件
return first;       // 简单场景
}else if(n == 2){            // 递归终止条件
return second;      // 简单场景
}else if (n == 3) {         // 递归终止条件
return first   second;      // 简单场景
}
return optimizeFibonacci(second, first   second, n - 1);  // 相同重复逻辑,缩小问题规模
}
return -1;
}
2.汉诺塔问题

古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。
*有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,
*小盘在上。在移动过程中可以利用B座。要求输入层数,运算后输出每步是如何移动的。

/**     
* @description 在程式中,我們把最上面的盘子称为第一個盘子,把最下面的盘子称为第N個盘子
* @author rico       
* @param level:盘子的個數
* @param from 盘子的初始地址
* @param inter 转移盘子時用於中转
* @param to 盘子的目的地址
*/
public static void moveDish(int level, char from, char inter, char to) {
if (level == 1) { // 递归终止条件
System.out.println("从"   from   " 移动盘子"   level   " 号到"   to);
} else {
// 将evel-1個盘子從from移到inter(不是一次性移動,每次只能移动一個盘子,其中to用于周转)
moveDish(level - 1, from, to, inter); // 相同重复逻辑,缩小问题规模
// 将第level個盘子从A座移到C座
System.out.println("从"   from   " 移东盘子"   level   " 號到"   to); 
// 将level-1個盘子从inter移到to,from 用于周转
moveDish(level - 1, inter, from, to); // 相同重复逻辑,缩小问题规模
}
}
public static void main(String[] args) {
int nDisks = 30;
moveDish(nDisks, 'A', 'B', 'C');
}

相关文章

  • 递归算法的奥妙

    递归是什么 递归算法是计算机科学中非常重要的一个概念,用于解决很多的计算机科学问题。是一种直接或者间接调用自身函数...

  • 快速幂模板

    递归算法 非递归算法

  • python递归算法、尾递归算法及优化

    文章概述 递归算法和尾递归概述递归算法的优化 递归算法 介绍:递归算法是计算机编程领域非常重要的一种算法,采用分而...

  • Java递归算法详解

    递归算法是一种直接或者间接调用自身函数或者方法的算法。Java递归算法是基于Java语言实现的递归算法。递归算法的...

  • C++ 递归算法

    递归算法,尾递归算法求阶乘!

  • 矩阵链乘法

    递归算法: 迭代算法: 分析 递归算法:规模为n的问题,有n个递归,每个递归又有相应矩阵个数个递归,故T(n)=T...

  • 【Python】(十一)从汉诺塔看Python中的递归问题

    递归的原则 递归算法必须具有基本情况。 递归算法必须改变其状态并向基本情况靠近。 递归算法必须以递归方式调用自身 ...

  • 一、算法

    目标 递归算法查找算法算法分析十大排序算法 递归算法 什么是递归递归,在数学与计算机科学中,是指在函数的定义中使用...

  • 欧几里得算法

    非递归算法 默认输入 m>=n 递归算法

  • 二叉树三种遍历的实现(递归)

    前序递归遍历算法:访问根结点-->递归遍历根结点的左子树-->递归遍历根结点的右子树 中序递归遍历算法:递归遍历根...

网友评论

      本文标题:递归算法的奥妙

      本文链接:https://www.haomeiwen.com/subject/zqivhktx.html