分治算法解决汉诺塔问题

本文介绍了分治算法的基本概念和步骤,重点阐述了如何将复杂问题分解为更小的子问题,以汉诺塔问题为例详细讲解了分治策略的应用,并提供了Java代码实现。
摘要由CSDN通过智能技术生成

1.分治算法介绍

        分治算法在算法中是很重要的算法。简单明了就是先分而治。就是把一个问题分成多个相同或者相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即是子问题的解的合并。很多常用的高效算法(快速排序,归并排序,二分搜索......)都是以分治算法为基础的

2.分治算法基本步骤

        分治算法在每一层的递归上可分为三个步骤

  • 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题 
  • 解决:若子问题规模较小而容易被解决则直接解,否则递归的解各个子问题
  • 合并:将各个子问题的解合并为原问题的解

3.汉诺塔问题

3.1.汉诺塔背景

        汉诺塔 (Tower of Hanoi),又称 河内塔 ,是一个源于 印度 古老传说的 益智玩具 。 大梵天 创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大梵天命令 婆罗门 把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。 并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 汉诺塔的来源 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。 印度教的主神 梵天 在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。

3.2.实现

        我们这里把三根柱子分别叫做A,B,C,初始盘都放在A柱,目标要放入C柱

  1. 如果只有一个圆盘,那我们直接把圆盘从A->C
  2. 如果圆盘数n>=2,那我们就可以把圆盘看成两个盘,1.最上面的盘  2.最下面的盘
  3. 那我们的大步骤就只有三步
    1. 先把最上面的所有盘 A->B
    2. 把最下面的盘A->C
    3. 把B塔的所有的盘B->C
  4. 这里就用到了分治,以我们三个盘举例,最上面的盘有两个,目标是移动到B柱,那我们就假设把B柱和C柱换个位置,这就相当于我么移动两个盘移动到目标柱,那还是把这两个盘分上盘和下盘,上面第一个盘得到目前的C柱子,最下面的盘到B柱子,再把目前C柱子上的盘移动到B柱子,也就是我上面写的三步。如果是四个盘我们最上面就是三个盘移动到实际的B柱子,那我们最上面的三个盘又分治成最上面两个盘移动。
  5. 根据4.我们已经把最上面的盘移动到B柱,那我们最下面的盘就从A->C
  6. 然后我们再把B柱上的所有盘移动到C柱子,
    1. 这里我们又可以看成是两个盘要移动到目标为C的柱
    2. 就要先把最上面的盘移动到A柱子,再把最下面的盘子移动到C柱
    3. 我们可以把柱子的顺序看成B,A,C,然后重复那三步

3.3.具体代码

        我这里使用Java演示代码实现

 //这里的char c 始终要是我们的目标柱子 ,char a 传的始终是我们的初始柱子(即要移动的盘子所在的位置)
    public static void hanoiTower(int num ,char a ,char b ,char c){
        //如果只有一个盘,初始柱子a 目标柱子就是c直接从a->c
        if(num == 1){
            System.out.println("第1个盘从 " + a + "->" + c);
        }else {
            //如果我们有n => 2情况 ,我们总是可以看做是两个盘 ,最下面的盘,最上面的盘
            //1.先把最上面的所有盘 A->B,那我们的初始柱子a,目标柱子就是b,所有把b传给char c
            hanoiTower(num -1 ,a,c,b);
            //2.把最下面的盘A->C 
            System.out.println("第"+num+"个盘从 "+ a + "->" + c);
            //3.把B塔的所有的盘B->C 初始柱子b,目标柱子c ,所有把b传给char a
            hanoiTower(num - 1 , b , a ,c);

        }
    }

        注:讲的不是很详细,可以先去听听尚硅谷的《数据结构与算法(Java数据结构与算法)》p155 ,如果不理解再来看看这个。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值