汉诺塔

汉诺塔——递归

别说谁变了你拦得住时间么 提交于 2019-12-03 02:36:35
汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作? 假如有三根柱子: 1、过程分析: (1)当只有两个盘子的时候(移动两次): a--b a--c b--c (2)当有三个盘子的时候: 应该考虑将最上层的两个较小的盘子先从a移动到b,然后将a上的最大的盘子(最底层)移动到c。 将最上层的盘子移到c; 中间的盘子移到b; 再将第一步的c上的盘子移动到b; 至此,最上层的两个盘子已经成功的移动到了b。 现在,需要将a柱子上的最下层的盘子移动到c柱子上。 然后再将a柱子作为辅助位,b柱子作为起点,c柱子作为终点,将b上的两个盘子移动到c即可。 ...... (3)当有n个盘子的时候,需要先将c柱子作为辅助位,a为起始位,b为终点。将上面的n-1个盘子从a移动到b。 然后将最下层的盘子从a移动到c。 最后将b上面的n-1个盘子从b移动到c。 2、代码实现: #include<stdio.h> void hanoi(int n,char A,char B,char C){//n代表 a柱子上面的盘子数量 if(n==1)

1.6 用栈来求解汉诺塔问题

匿名 (未验证) 提交于 2019-12-03 00:33:02
题目:汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有N层的时候,打印最优移动过程和最优移动总步数。 例如,当塔数为两层时,最上层的塔记为1, 最下层的塔记为2,则打印:   Move 1 from left to mid   Move 1 from mid to right   Move 2 from left to mid   Move 1 from right to mid   Move 1 from mid to left   Move 2 from mid to right   Move 1 from left to mid   Move 1 from mid to right 要求:   用以下两种方法解决:   方法一:递归的方法;   方法二:非递归的方法,用栈来模拟汉诺塔的三个塔。 方法一:递归的方法 1 // 用栈来求解汉诺塔问题 2 3 #include <iostream> 4 #include < string > 5 6 using namespace std; 7 8 int process( int num, string left, string mid, string right, string from , string to) 9 { 10 if

n阶汉诺塔问题(递归)

匿名 (未验证) 提交于 2019-12-03 00:32:02
【汉诺塔】 汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说:大梵天创造世界的时候做了三根 金刚石 柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 【分析】 设A柱上原始盘子数量为n,则当n=1时,只需将盘子从A->C即可;否则 1.用C柱过渡,将A柱上的n-1个盘子移到B柱上 2.将A柱上的最后一个盘子直接移到C柱上 3.用A柱过渡,将B柱上的n-1个盘子移到C柱上 【代码实现】 #include<iostream> using namespace std; int m=0; void move(char A,int n,char C) { cout<<++m<<'.'<<n<<"号盘从"<<A<<"->"<<C<<endl; } void hanoi(int n,char A,char B,char C) { if(n==1) move(A,1,C); else { hanoi(n-1,A,C,B); move(A,n,C); hanoi(n-1,B,A,C); } } main() { int n; while(cin>>n) hanoi(n,'A','B','C'); return 0; } 文章来源: n阶汉诺塔问题

汉诺塔的解法

匿名 (未验证) 提交于 2019-12-03 00:28:02
问题描述: 据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小 至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的 原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。 简单汉诺塔的迭代实现: public class HanioTowerTest { public static void moveDish ( int level, char from , char assistant, char to){ if (level == 1 ){ System. out .println( "从" + from + "移动1号到" + to); } else { moveDish(level - 1 , from , to, assistant); System. out .println( "从" + from + "移动" + level + "号到" + to); moveDish(level - 1 , assistant, from , to); } } public static void main (String[] args){ final int LEVEL = 3 ; moveDish(LEVEL,

递归之汉诺塔

匿名 (未验证) 提交于 2019-12-03 00:22:01
用C语言实现。 #include <stdio.h> #include <stdlib.h> void hannuota(int n,char A,char B,char C); void hannuota(int n,char A,char B,char C){ /* 如果是一个盘子,直接将盘子从A移动到C 否则,先将A柱子上的n-1个盘子借助C移到B 最后将B柱子上的n-1个盘子借助A移到C */ if(n == 1){ printf("将编号为%d的盘子直接从%c柱子移动到%c柱子\n",n,A,C); }else{ hannuota(n-1,A,C,B); printf("将编号为%d的盘子直接从%c柱子移动到%c柱子\n",n,A,C); hannuota(n-1,B,A,C); } } int main() { char ch1 = 'A'; char ch2 = 'B'; char ch3 = 'C'; int n; printf("请输入要移动盘子的个数:\n"); scanf("%d",&n); hannuota(n,'A','B','C'); return 0; } 文章来源: 递归之汉诺塔

图解汉诺塔问题(递归求解)

匿名 (未验证) 提交于 2019-12-03 00:21:02
汉诺塔: 单看这个问题描述有点让人抓瞎,这是当然,无论多么简单的问题描述,在没有建立具体地模型之前都是让人不知所云的,仅仅用生活中的语言去描述一些数学或算法问题往往会让听者产生理解偏差, 这也和每个的理解能力和思维方式有很大关系,这就显示出数学的强大了,数学让问题不再模糊,参数和公式组成的模型让问题不再有理解偏差和误区,只可惜数学没学好,看来以后还得回来把高数、概率论这些给补回来。 说了一些题外话,下面来对汉诺塔问题进行解释和建立模型 下面我用图来描述64个盘子的转移流程 using System; using System.Collections.Generic; namespace 汉诺塔问题_递归解决 { class Program { static void Main(string[] args) { HanNuo(64, 'a', 'b', 'c'); Console.ReadKey(); } /// <summary> /// 汉诺塔问题解决方法 /// </summary> /// <param name="n">汉诺塔的层数</param> /// <param name="a">承载最初圆盘的柱子</param> /// <param name="b">起到中转作用的柱子</param> /// <param name="c">移动到的目标柱子</param>

汉诺塔问题(分治递归思想)

匿名 (未验证) 提交于 2019-12-02 23:56:01
汉诺塔的基本思想就是 1.先把上面n-1个通过c转移到b(因为我的c里面要放n,也就是最大的那个) 2.把a中的 n(最大的那个)移动到c 3.再把b中的n-1个通过a移动到c; 整个过程就结束了,然后递归调用这个函数,每一层递归都执行这三个步骤 最后n=1的时候,想象一下,n=1的时候,是不是把c中的1直接移到c中即可,所以这就是终止条件。今天可算是理解了汉诺塔的原理了!!!` `` #include using namespace std; void movef(int n,char a,char b){ cout<<“把”<<n<<“从”<<a<<“移动到”<<b<<endl; } void haniod(int n,char a,char b,char c){ if(n==1){ movef(n,a,c); }else{ haniod(n-1,a,c,b); movef(n,a,c); haniod(n-1,b,a,c); } } int main(){ int n; cin>>n; haniod(n,‘a’,‘b’,‘c’); } 来源:51CTO 作者: 北派胖子 链接:https://blog.csdn.net/qq_43568790/article/details/100147676

汉诺塔

匿名 (未验证) 提交于 2019-12-02 23:55:01
''' 问题: 有三个柱子A、B、C。移动n个盘子从 A -> C 分析: 步骤1: 移动前n-1个盘子 A -> B 步骤2: 移动第n个盘子 A -> C 步骤3: 移动前n-1个盘子 B -> C 实验: (n个盘子从上到下编号:1, 2, 3,...,n) n=2: move 1 A -> B 步骤1:移动前n-1个盘子 A -> B move 2 A -> C 步骤2:移动第n个盘子到 A -> C move 1 B -> C 步骤3:移动前n-1个盘子 B -> C n=3: move 1 A -> C move 2 A -> B move 1 C -> B 移动前n-1个盘子 A -> B move 3 A -> C 移动第n个盘子到 A -> C move 1 B -> A move 2 B -> C move 1 A -> C 移动前n-1个盘子 B -> C n=4: 4 A C 3 A B 4 C B 2 A C 4 B A 3 B C 4 A C 可以看到, 要把盘子A->B 要通过C, 把盘子从B->C要通过A def move(n, start,end, middle) move n start -> middle move n-1 start -> end move n middle-> end if n==1: move 1 A -> C move

彻底解决汉诺塔问题――递归算法

匿名 (未验证) 提交于 2019-12-02 23:34:01
关于递归: 一定不要试图跟踪大型递归的过程! 要写出递归,关键就是找出递归的递归方程式: 也就是说,要完成最后一步,那么最后一步的前一步要做什么。 1)在求f(n, other variables)的时候,你就默认f(n -1, other variables)已经被求出来了――至于怎么求的,这个是计算机通过回溯求出来的 PS:这里用到了一种叫做栈(stack)的先进后出的数据结构,所以递归输出的答案一般是自下而上的。 (2)递归和二叉树是密切相关的。可以尝试通过二叉树的数据结构来理解递归是如何将一个问题拆分成若干子问题,求解再回溯的。这里可以参考以下快速排序(QuickSort)的过程(快速排序的核心思想是分治,分治即分而治之,通过递归将原问题分解为若干容易求解的子问题,再通过递归将这些子问题联系起来并向二叉树的上层回溯,最终求解出原问题) 对于这个汉诺塔问题,在写递归时,我们只需要确定两个条件: 1.递归何时结束? 2.递归的核心公式是什么?即: 怎样将n个盘子全部移动到C柱上? 即:若使n个盘子全部移动到C柱上,上一步应该做什么? 下面正式进入该题: 汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘

20190710-汉诺塔算法

匿名 (未验证) 提交于 2019-12-02 22:51:30
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界 的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵 天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘 上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 关键点: 一次只能移动一个盘子 大盘不能重叠在小盘子上 当n=1的时候 1. 直接将1从X移动到Z 当n=2的时候 1. 将1从X移动到Y轴 2. 将2从X移动到Z轴 3. 将1从Y移动到Z轴 当n=3的时候 1. 将1从X移动到Z 2. 将2从X移动到Y 3. 将1从Z移动到Y 4. 将3从X移动到Z 5. 将1从Y移动到X 6. 将2从Y移动到Z 7. 将1从X移动到Z 当n=4的时候 当前挪动的盘子为1,挪动轨迹为x==>y 当前挪动的盘子为2,挪动轨迹为x==>z 当前挪动的盘子为1,挪动轨迹为y==>z 当前挪动的盘子为3,挪动轨迹为x==>y 当前挪动的盘子为1,挪动轨迹为z==>x 当前挪动的盘子为2,挪动轨迹为z==>y 当前挪动的盘子为1,挪动轨迹为x==>y 当前挪动的盘子为4,挪动轨迹为x==>z 当前挪动的盘子为1,挪动轨迹为y==>z 当前挪动的盘子为2,挪动轨迹为y==>x 当前挪动的盘子为1,挪动轨迹为z==>x 当前挪动的盘子为3,挪动轨迹为y==>z