首页 > 其他分享 >汉诺塔问题——分而治之(引入递归,解决重复子问题)

汉诺塔问题——分而治之(引入递归,解决重复子问题)

时间:2023-03-11 21:23:24浏览次数:47  
标签:柱子 递归 求解 圆盘 分而治之 重复子 层塔 汉诺塔 移动

汉诺塔问题的引入:

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。 (ps:来自于百度)

 1.求解思路:

假设只有一层塔,那么就只需要将a移动到c即可;

假设有二层塔,需要先将前一个小圆盘从a移动到b,再将最后大圆盘1个移动到c,再将b中的小圆盘从b移动到c;

假设有三层塔,需要先将前两个小圆盘从a移动到b,再将最后大圆盘1个移动到c,再将b中的小圆盘从b移动到c;

……

假设有n-1层塔,需要先将前n-2个小圆盘从a移动到b,再将最后大圆盘1个移动到c,再将b中的小圆盘从b移动到c;

假设有n层塔,需要先将前n-1个小圆盘从a移动到b,再将最后大圆盘1个移动到c,再将b中的小圆盘从b移动到c;

 

由上述观察可知:求解第二层塔与第n层塔的解题步骤是一致的,求解第n层塔需要求解第n-1层塔;求解第n-1层塔需要求解第n-2层塔………求解第三层塔需要求解第二层2塔,可以将其看成一个等比数列,每次的都需要比上一次多进行一倍操作,由等比数列求和公式得,总共进行了2^n-1次移动,所以时间复杂度为O(2^n)!

 

2.如何求解:

从上述不难看出,每次求解的步骤都一样,那有没有有什么方法解决重复的问题呢?

————递归会给你答案

什么是递归:递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。(ps:来自于百度)

 

递归实际上就是一种自调用函数,自己调用自己,从而达到解决重复步骤的问题;

 

如果汉诺塔只有一层的时候我们就需要把a移动到c

如果2层以上呢:由于递归函数再求解过程中不会改变步骤,每次都是固定从a移动到c,所以我们要将每根柱子做一个标记,方便理解交换时所带来的里面元素的改变过程;设:

第一个柱子为交换柱子:需要移动的元素都放在第一个位置

第二个柱子为中间柱子:不需要移动元素放在第二个柱子里

第三个柱子为目标柱:将要移动的元素放到第三个柱子

现在递归循环是从第二层到第n层开始的:

      1.从上一层结束开始c元素在目标柱中,所以需要交换到目标柱当中(c元素)

  2.将a移动到b,所以a元素在交换柱,b元素在目标柱

  3.然后将b移动到c,b为交换柱,c为目标柱,a在中间柱子

3.代码实现

void Hannouta(int n, char pos1, char pos2, char pos3)
{
     if (n == 1) 
    {
        move(n, pos1, pos3);//move为交换函数
    }
    else
    {
        Hannouta(n-1, pos1, pos3, pos2); 
        move(n, pos1, pos3);
         printf("盘子%d: 从 %c柱 移动到 %c柱\n", n, pos1, pos3);
        Hannouta(n-1, pos2, pos1, pos3);
    }
}

 

4.时间复杂度分析

由上述分析可知道——时间复杂度为O(2^n);

              

 

标签:柱子,递归,求解,圆盘,分而治之,重复子,层塔,汉诺塔,移动
From: https://www.cnblogs.com/higer-TSW/p/17206990.html

相关文章

  • 关于汉诺塔的最简单理解
    最简单的汉诺塔算法解析,看不懂可以刀我今天给大家带来一个汉诺塔算法的讲解,应该是最简单的理解方法,首先我们得知道汉诺塔游戏规则,不会有人搜这个然后不知道规则吧?不会吧?......
  • 【算法训练营day52】LeetCode300. 最长递增子序列 LeetCode674. 最长连续递增子序列 L
    LeetCode300.最长递增子序列题目链接:300.最长递增子序列独上高楼,望尽天涯路感觉和之前的动态规划思路还不一样,没有想出好的递推公式。慕然回首,灯火阑珊处解决这道题......
  • 【LeeCode】718. 最长重复子数组
    【题目描述】给两个整数数组 ​​nums1​​ 和 ​​nums2​​ 两个数组中 公共的 、长度最长的子数组的长度 。​​​https://leetcode.cn/problems/maximum-length-......
  • 汉诺塔
    汉诺塔是计算机学教科书中常用的游戏,用来说明递归的魔力。该游戏有3个柱子和一组不同大小的圆盘,柱子从圆盘的中心穿过。题目描述设abc是三个塔座,开始时,在塔座a上有一叠......
  • 【LeetCode字符串#06】KMP巩固练习:重复子串
    重复的子字符串力扣题目链接(opensnewwindow)给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。......
  • 汉诺塔问题
    参考递归实现汉诺塔//汉诺塔递归版#include<stdio.h>//解决n个盘从a移到c,其中b为辅助的递归函数voidHanoi(intn,inta,intb,intc){//n:要移动的盘子的数量......
  • AcWing 799. 最长连续不重复子序列
    (双指针算法优化)思路:暴力解法:for(inti=0;i<n;i++)for(intj=0;j<=i;j++)check(i,j);算法优化:找到某种性质,尤其注意解题过程中存在的......
  • 【CCCC】L2-025 分而治之 (25分),图的度数,使节点独立的方案
    problemL2-025分而治之(25分)分而治之,各个击破是兵家常用的策略之一。在战争中,我们希望首先攻下敌方的部分城市,使其剩余的城市变成孤立无援,然后再分头各个击破。为此参谋......
  • P1242 新汉诺塔
    新汉诺塔题目描述设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A,B,C,这个状态称为初始状态......
  • P4285 [SHOI2008]汉诺塔
    [SHOI2008]汉诺塔题目描述汉诺塔由三根柱子(分别用A、B、C表示)和n个大小互不相同的空心盘子组成。一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形......