数据结构(十二)递归的应用--汉诺塔问题

  一、汉诺塔问题描述

  设有三根标号为A,B,C的柱子,在A柱子上放着n个盘子,每个逗比下面的略小一点,要求把A上的盘子全部转移到C上,移动的规则是:①一次只能移动一个盘子;②移动过程中大盘子不能放在小盘子上面;③在移动过程中盘子可以放在A,B,C的任意一个柱子上。

 

  二、用递归方法求解n个盘子的汉诺塔问题的基本思想

  一个盘子的汉诺塔问题可以直接移动(递归出口)。

  n个盘子的汉诺塔问题可递归表示为:首先把上边的n-1个盘子从A移动B,然后把最下边的一个盘子从A移到C(直接求解),最后把移到B的n-1个盘子移到C。

 

  三、用递归求解汉诺塔问题的实现

  1.算法实现

package bigjun.iplab.HanoiTowers;

public class HanoiTowers {

    public static void hTowers(int n, char form, char to, char via) {
        
        // 递归出口,n=1只有一个盘子时,直接从A移到C
        if (n == 1) {
            System.out.println("移动盘子1从" + form + "到" + to);
            return;
        }
        
        // 将n-1个盘子从A借助C移到B
        hTowers(n - 1, form, via, to);
        
        System.out.println("移动盘子" + n + "从" + form + "到" + to);
        
        // 将n-1个盘子从B借助A移到C
        hTowers(n - 1, via, to, form);
    }
    
    
    public static void main(String[] args) {
        // 将4个盘子从A借助B移到C
        hTowers(4, 'A', 'C', 'B');
    }
}

  2.输出

移动盘子1从A到B
移动盘子2从A到C
移动盘子1从B到C
移动盘子3从A到B
移动盘子1从C到A
移动盘子2从C到B
移动盘子1从A到B
移动盘子4从A到C
移动盘子1从B到C
移动盘子2从B到A
移动盘子1从C到A
移动盘子3从B到C
移动盘子1从A到B
移动盘子2从A到C
移动盘子1从B到C

  3.结合输出分析代码执行过程

将4个盘子从A借助B移到C可分为如下过程:
将3个盘子从A借助C移到B,然后再将1个盘子从A移到C,最后把3个盘子从B移到C
将3个盘子从A借助C移到B可分为如下过程:
  将2个盘子从A借助B移到C,然后再将1个盘子从A移到B,最后把2个盘子从C移到B
将2个盘子从A借助B移到C可分为如下过程:
  将1个盘子从A移到B,然后将1个盘子从A移到C,最后将1个盘子从B移到C

 

  四、算法分析

  递归算法把移动n个盘子的汉诺塔问题分解为移动n-1个盘子的汉诺塔问题,把移动n-1个盘子的问题分解成n-2个盘子的问题,...,把移动两个盘子的汉诺塔问题分解成移动一个盘子的汉诺塔问题。对于一个盘子的汉诺塔问题则直接求解(即直接移动)。在一个盘子的汉诺塔问题解决后,可以解决两个盘子的汉诺塔问题,...,在n-1个盘子的汉诺塔问题解决后,可以解决n个盘子的汉诺塔问题。这样n个盘子的汉诺塔问题最终就得以解决。

posted @ 2018-06-15 16:16  BigJunOba  阅读(582)  评论(0编辑  收藏  举报