汉诺塔-Hanoi

1. 问题来源:

汉诺塔(河内塔)问题是印度的一个古老的传说。

  法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

  后来,这个传说就演变为汉诺塔游戏,玩法如下:
  (1). 有三根杆子A,B,C。A杆上有若干碟子
  (2). 每次移动一块碟子,小的只能叠在大的上面
  (3). 把所有碟子从A杆全部移到C杆上

2. 解题思路:

  题中只给了三座塔,我们利用B塔将圆盘全部移动到在C塔。

  为了将N个盘子从A移动到C,需要先将第N个盘子上面的N-1个盘子移动到B上,这样才能将第N个盘子移动到C上。

  同理,为了将第N-1个盘子从B移动到C上,需要将N-2个盘子移动到A上,这样才能将第N-1个盘子移动到C上。

  通过递归就可以实现汉诺塔问题的求解。

3. 源代码:

 1 public class Hanoi {
 2
 3     private static void move(int level, char from, char inter, char to) {
 4         if (level == 1) {
 5             System.out.println(level + ":" + from + "->" + to);
 6         } else {
 7             move(level - 1, from, to, inter);
 8             System.out.println(level + ":" + from + "->" + to);
 9             move(level - 1, inter, from, to);
10         }
11     }
12
13     public static void move(int level) {
14         move(level, ‘A‘, ‘B‘, ‘C‘);
15     }
16 }

测试代码:

1 public class Main {
2     public static void main(String[] args) {
3         int nDisks = 3;
4         Hanoi.move(nDisks);
5     }
6 }

测试结果:

1:A->C
2:A->B
1:C->B
3:A->C
1:B->A
2:B->C
1:A->C

当然,在这里圆盘的个数nDisks可以通过java.util.Scanner从控制台进行读入:

 1 import java.util.Scanner;
 2
 3 public class Main {
 4     public static void main(String[] args) {
 5         Scanner in = new Scanner(System.in);
 6         int nDisks = in.nextInt();
 7         in.close();
 8         Hanoi.move(nDisks);
 9     }
10 }

汉诺塔问题的时间复杂度为O(2^n)

时间: 2024-10-18 22:06:58

汉诺塔-Hanoi的相关文章

汉诺塔 Hanoi Tower

一个古老的印度传说:在世界的中心贝拿勒斯的圣庙里,一块黄铜板上插着三支宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上穿好了由大到小的64片金片,这就是所谓的汉诺塔(Hanoi Tower).不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面. 僧侣们预言,当所有的金片从梵天穿好的金片上移到另一根针上时,世界末日就会来临,而梵塔.寺庙和众生也会随之灭亡...... 故事不多说了,汉诺塔是递归思想的典型应用,上代码: 1 #i

汉诺塔hanoi

问题描述: 有一个梵塔,塔内有三个座A.B.C,A座上有诺干个盘子,盘子大小不等,大的在下,小的在上(如图). 把这些个盘子从A座移到C座,中间可以借用B座但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘 子始终保持大盘在下,小盘在上. 描述简化:把A柱上的n个盘子移动到C柱,其中可以借用B柱. #include <bits/stdc++.h> using namespace std; void move(int n, char f, char t) { static int cnt

Algorithm系列之汉诺塔(Hanoi)

作者:i_dovelemon 来源:CSDN 日期:2014 / 11 4 主题: 递归, Hanoi 引言 在算法的世界里,有递归这样一个强大的工具.很多的算法,我们都可以使用递归来实现,并且非常的简单,容易理解.今天,我们就来讲解一个使用递归解决的问题.著名的汉诺塔问题,就能够使用递归算法来解决.我们先来了解汉诺塔问题是什么: 汉诺塔问题最早由一个法国数学家卢卡斯在1890年发表的,当时的版本是这样的,当64个圆盘被从梵塔上移走的时候,世界末日也就来临了.如果祭司每一分钟移动一个圆盘,请估计

用函数递归的方法解决古印度汉诺塔hanoi问题

问题源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 我们把柱子依次命名为A,B,C 从只有一个圆盘考虑:直接就是A-->C 两个圆盘的时候就是:A-->B,A-->C,B-->C 三个圆盘的时候就是:A-->C,A-->B,C-->B,A-->C,

数据结构与算法—递归(阶乘、斐波那契、汉诺塔)

目录 递归介绍 递归求阶乘 递归求斐波那契 递归解决汉诺塔 总结 递归介绍 递归:就是函数自己调用自己. 子问题须与原始问题为同样的事,或者更为简单:递归通常可以简单的处理子问题,但是不一定是最好的.对于递归要分清以下概念: 自己调用自己 递归通常不在意具体操作,只关心初始条件和上下层的变化关系. 递归函数需要有临界停止点,即递归不能无限制的执行下去.通常这个点为必须经过的一个数. 递归通常能被其他方案替代(栈.数组正向求). 认识递归,递归函数通常简易但是对于初学者可能很难取理解它.拿一个递归

汉诺塔问题(Hanoi)的C++代码实现

1 #include <iostream> 2 using namespace std; 3 //第一个塔为初始塔,第二个塔为中转塔,第三个塔为目标塔 4 5 int i = 1; //记录步数 6 void move(int n,char from,char to) //将编号为N的盘子由from塔转移到to塔 7 { 8 cout<<"第"<<i++<<"步:将"<<n<<"号盘子

Hanoi(汉诺)塔问题(C实现)

Hanoi(汉诺)塔问题.这是一个经典的数学问题:古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个老和尚想把这64个盘子从A座移到C座,但每次只允许移动一个盘子,且在移动过程中在3个座上都始终保持大盘在下,小盘在上.在移动过程中可以利用C座,给出移动过程. #include<stdio.h> #include<stdlib.h> void move(char ch1,char ch2) {  printf("%c-

Hanoi(汉诺塔问题)用栈来求解

学习c语言必定会遇到递归问题,学递归一定知道汉诺塔问题:如何将圆盘移动到另一根柱子上,但是圆盘的顺序不能改变. 有XYZ三个轴,n个盘子放在X轴上,目标是将N个盘子从X轴上移动到Z轴上 这里我们假设有这样一个方法F,F:将N个盘子按照原来的顺序从X轴上移动到Z轴上 如果只有一个盘子的话,一步到位 但是有N个(N>1)是,为了实现目标,我们需要利用中间轴来倒腾,我们将最后一个盘子上方的N-1个盘子按照顺序不变的方式(方法F)(这并不是移动步数最少的办法)先移动到Y轴,在将最后一个剩余的盘子移动到Z

URAL 2029 Towers of Hanoi Strike Back 汉诺塔,从初始状态到任意给出状态需要的次数

F - Towers of Hanoi Strike Back Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 2029 Description The Tower of Hanoi puzzle was invented by French mathematician édouard Lucas in the second half