11递归---解析案例汉诺塔问题和斐波那契数列

前言

数据结构和算法的最终目标都是降低时间复杂度。

数据结构是从数据组织形式的角度达成这个目标;算法则是从数据处理的角度达成这个目标。

1、什么递归

通俗解释就是某个函数自己调用自己。

递归的两层含义:

(1)递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,并且这些子问题可以用完全相同的解题思路来解决。

(2)递归问题的演化过程是一个对原问题从大到小进行拆解的过程,并且会有一个明确的终点(临界点)。一旦原问题到达了这个临界点,就不用了再往更小的问题上进行拆解了。最后,从这个临界点开始,把小问题的答案按照原路返回,原问题便得以解决。

总结:

(1)递归的基本思想就是把规模大的问题转化为规模小的相同的子问题来解决。

(2)递归必须有明确的结束条件,也就说递归的实现包含了两个部分:一个是递归主体,另一个是终止条件。

递归代码关键在于,写出递推公式和找出终止条件。

2、汉诺塔问题

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。

操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

11递归---解析案例汉诺塔问题和斐波那契数列_第1张图片         11递归---解析案例汉诺塔问题和斐波那契数列_第2张图片        11递归---解析案例汉诺塔问题和斐波那契数列_第3张图片

将问题拆解为以下3个小问题:

(1)把从小到大的n-1个盘子,从a移动到b;

(2)将a杆中剩下的第n号盘移至c杆;

(3)以a杆为中介,将b杆1到n-1转移至c杆。

一、判断递归的第一个条件

显然,第1和第3个问题就是汉诺塔问题。

二、判断它是否满足终止条件

随着递归体不断缩小范围,汉诺塔问题由原来“移动从小到大的n个盘子”,缩小为“移动从小到大的n-1个盘子”,直到缩小为“移动从小到大的1个盘子”。移动从小到大的1个盘子,就是移动最小的那个盘子。根据规则可以发现,最小盘子是可以自由移动的。因为递归的第二个条件也是满足的。

具体代码如下所示,在代码中,hanio(n,a,b,c),代表把n个盘子由a移动到c。根据分析,我们知道递归体包含3个步骤:

(1)把从小到大的n-1个盘子从x移动到y,那么代码就是hanio(n-1,x,z,y);

(2)再把最大的一个盘子从x移动到z,那么直接完成一次移动的动作就可以了;

(3)再把从小到大的n-1个盘子从y移动到z,那么代码就是hanio(n-1,y,x,z)。对于终止条件则需判断n的大小。如果n等于1,那么直接移动就可以了。

public static void main(String[] args) {

    String x = "x";

    String y = "y";

    String z = "z";

    hanio(3, x, y, z);

}

public void hanio(int n, String x, String y, String z) {

    if (n < 1) {

        System.out.println("汉诺塔的层数不能小于1");

    } else if (n == 1) {

        System.out.println("移动: " + x + " -> " + z);

        return;

    } else {

        hanio(n - 1, x, z, y);

        System.out.println("移动: " + x + " -> " + z);

        hanio(n - 1, y, x, z);

    }

}

递归的核心思想是把规模大的问题转化为规模小的相似的子问题来解决

-------------------------------------------------------------------------------------------------------------------

例二:斐波那契数列

斐波那契数列是:0,1,1,2,3,5,8,13,21,34,55,89,144……

首先,我们可以发现,这个数列元素的特点是从第三项开始每一项等于它前两个数之和,由此我们可以推出数列的第n个元素An=A(n-1)+A(n-2)(n>=3)

    public static int fibonacci(int n){
        if(n==1) return 0;
        if(n==2) return 1;

        return fibonacci(n-1)+fibonacci(n-2);
    }

 

你可能感兴趣的:(数据结构与算法,算法,java,递归算法)