汉若塔问题的迭代解法

先看递归解法,用Perl语言一分钟不到就写完了。

sub hanno_recursive {

my ($from, $to, $reserve, $n) =  @_;

if (1 == $n) {

print "move $n from $from to $to\n";

return;

}

hanno_recursive($from, $reserve, $to, $n -1);

print "move $n from $from to $to\n";

hanno_recursive($reserve, $to, $from, $n -1);

}

极其简洁优美。充分体现了递归的优雅。

接下来,考虑迭代解法。考虑将问题分解为树结构。很显然, 将A   B  C看成一个圈, 则左右子树具有某种对称。即顺时针或逆时针旋转。

这样,我们完全可以通过左树求得右树, 问题变成为了线性递归, 这个很容易转换为迭代。

原理知道了, 写这个代码,还是比较费劲, 花了1个小时才调好。

sub hanno_iterate {

my ($from, $to, $reserve, $n) =  @_;

my @left = ();

my @right = ();

#move to leaf node

my $count = $n;

while ($count > 1) {

my $tmp = $to;

$to = $reserve;

$reserve = $tmp;

$count--;

}

for (my $index = 1; $index <= $n; $index++) {

my $new = "move $index from $from to $to\n";

push @left, $new;

while ($new = shift @right) {

push @left, $new;

}

last if ($index == $n);

if (($index % 2) == ($n % 2)){

# anti-clock $from -> $to, $reserve->$from, $to -> $reserve

foreach my $opt(@left) {

my $left_value = "$opt";

$left_value =~ tr/ABC/CAB/;

push @right, $left_value;

}

} else {

# clock $from -> $reserve, $reserve->$to, $to -> $from

foreach my $opt(@left) {

my $left_value = "$opt";

$left_value =~ tr/ABC/BCA/;

push @right, $left_value;

}

}

my $tmp = $to;

$to = $reserve;

$reserve = $tmp;

}

foreach my $opt(@left) {

print $opt;

}

}

时间: 2025-01-16 12:55:44

汉若塔问题的迭代解法的相关文章

汉诺塔问题的递归解法

汉诺塔问题的递归解法: 实现程序: #include<iostream> using namespace std; void move(int n, char i, char j) { cout << "把" << n << "号从" << i << "移动到" << j << endl; } void hanoi(int n, char x, cha

C#中汉诺塔问题的递归解法

百度测试部2015年10月份的面试题之——汉诺塔. 汉诺塔就是将一摞盘子从一个塔转移到另一个塔的游戏,中间有一个用来过度盘子的辅助塔. 百度百科在此. 游戏试玩在此. 用递归的思想解决汉诺塔问题就是分为两种情况: 第一种情况是只有一个盘子的情况,也就是最基本的情况,这种情况下,直接将该盘子从原始塔转移到目标塔即可胜利: 第二种情况是右n个盘子的情况,也就是普遍情况,这种情况下,要将除了最底下的那个盘子以外的(n-1)个盘子从原始塔转移到辅助塔,再把最底下的那个盘子(第n个盘子)从原始塔转移到目标

汉诺塔问题(用栈替代递归)

汉诺塔问题 古代有一个梵塔,塔内有三个座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图).有一个和尚想把这64个盘子从A座移到B座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上.在移动过程中可以利用B座,要求输出移动的步骤. 汉诺塔问题递归解法 C++代码 1 //By LYLtim 2 //2015.2.8 3 4 #include <iostream> 5 6 using namespace std; 7 8 void ha

汉诺塔问题的解法

汉诺塔问题移动N个盘子可以转化为先把N-1个盘子移动到b上面,再把最后一个盘子移动到C,最后把b上的N-1个盘子移动到C:其中N-1个盘子的移动和移动N-1个盘子的方式是一样的,只是把c换成了b,最后一个盘子移动到C之后,N-1个盘子再从b移过去就是把a换成了b. #include<stdio.h>#include<stdlib.h>//汉诺塔问题void hanoi(int n,char a,char b,char c){ if(n==1)  printf("%c-&g

汉诺塔问题求解

问题描述:A,B,C三个柱子,其中A插着n个盘子从上到下按照小到大放,尝试以B盘子为中介,每次移一次,将A中的盘子从上到下按照小到大插: 算法:n个盘子全放在A上面,分为两步走:将前面(n-1)个盘子全部放到B上面,然后将第n个盘子放到C中: 这样子B中就有(n-1)个盘子,再以A为中介,全部放到C中. 数学建模: 设n个盘子需要放An次, An=A(n-1)+1+A(n-1);n=a,An=1; 通过简单的迭代,即可求出An=2^n-1; 程序实现: hanoi(n,A,B,C) =Move(

【Python学习】Python解决汉诺塔问题

参考文章:http://www.cnblogs.com/dmego/p/5965835.html 一句话:学程序不是目的,理解就好:写代码也不是必然,省事最好:拿也好,查也好,解决问题就好! 信息时代不用信息就是罪过,直接抄不加理解与应用,就不是自己的,下次遇到还是不会,或许其中的某一个细节就能够用于各个问题的解决,共勉 学习一个东西总会遇到一些经典的问题,学习Python第二天尝试看一下汉诺塔问题,还是百度,看看解题思路,纯粹是重温初中课堂,越活越回去了 汉诺塔的图解递归算法 一.起源: 汉诺

Java学习(3):递归问题(举例:汉诺塔问题)。

递归问题是编写程序中常见的问题之一.此随笔对具有明显递归的汉诺塔问题进行说明. 1 import java.util.Scanner; 2 3 /** 4 * 递归:汉诺塔 5 * 6 * @author xcx 7 * @time 2017年7月3日上午8:16:07 8 */ 9 public class Hanoi { 10 private static int i = 0; 11 12 public static void main(String[] args) { 13 int n =

汉诺塔的图解递归算法

一.起源: 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘.大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上.并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘. 二.抽象为数学问题: 如下图所示,从左到右有A.B.C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上

算法系列之“汉若塔”

一.汉若塔 1.说明: 河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市:1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当