1.6 用栈来求解汉诺塔问题

题目:汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有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 (num == 1)
11     {
12         if ((from.compare(mid) == 0) || (to.compare(mid) == 0))
13         {
14             cout << "Move 1 from " << from << " to " << to << endl;
15             return 1;
16         }
17         else
18         {
19             cout << "Move 1 from " << from << " to " << mid << endl;
20             cout << "Move 1 from " << mid << " to " << to << endl;
21             return 2;
22         }
23     }
24     if ((from.compare(mid) == 0) || (to.compare(mid) == 0))     //处理将所有圆盘从“左”->“中”、“中”->“左”、“中”->“右”、“右”->“中”等情况
25     {
26         string another = ((from.compare(left) == 0) || (to.compare(left) == 0)) ? right : left;
27         int part1 = process(num - 1, left, mid, right, from, another);
28         int part2 = 1;
29         cout << "Move " << num << " from " << from << " to " << to << endl;
30         int part3 = process(num - 1, left, mid, right, another, to);
31         return part1 + part2 + part3;
32     }
33     else
34     {
35         int part1 = process(num - 1, left, mid, right, from, to);      //处理前N - 1个圆盘,从“from”到“to”
36         int part2 = 1;
37         cout << "Move " << num << " from " << from << " to " << mid << endl; //处理第N个圆盘,从“from”到“mid”
38         int part3 = process(num - 1, left, mid, right, to, from);     //处理前N - 1个圆盘,从“to”到“from”
39         int part4 = 1;
40         cout << "Move " << num << " from " << mid << " to " << to << endl;  //处理第N个圆盘,从“mid”到“to”
41         int part5 = process(num - 1, left, mid, right, from, to);      //处理前N - 1个圆盘,从“from”到“to”
42         return part1 + part2 + part3 + part4 + part5;                  //返回该次调用移动了多少步
43     }
44 }
45
46 int hanoiProblem1(int num, string left, string mid, string right)
47 {
48     if (num < 1)
49     {
50         return 0;
51     }
52     return process(num, left, mid, right, left, right);
53 }

方法二:非递归的方法

 1 enum Action {No, LToM, MToL, MToR, RToM};
 2
 3 static int fStackTotStack(Action &record, Action preNoAct, Action nowAct, stack<int> &fStack, stack<int> &tStack, string from, string to)
 4 {
 5     if (record != preNoAct && fStack.top() < tStack.top())
 6     {
 7         tStack.push(fStack.top());
 8         fStack.pop();
 9         cout << "Move " << tStack.top() << " from " << from << " to " << to << endl;
10         record = nowAct;
11         return 1;
12     }
13     return 0;
14 }
15
16 int hanoiProblem2(int num, string left, string mid, string right)
17 {
18     stack<int> lS;
19     stack<int> mS;
20     stack<int> rS;
21     lS.push(INT_MAX);
22     mS.push(INT_MAX);
23     rS.push(INT_MAX);
24     for (int i = num; i > 0; i--)
25     {
26         lS.push(i);
27     }
28     Action record = No;
29
30     int step = 0;
31     while(rS.size() != num + 1)
32     {
33         step += fStackTotStack(record, MToL, LToM, lS, mS, left, mid);  //“左”->“中”
34         step += fStackTotStack(record, LToM, MToL, mS, lS, mid, left);  //“中”->“左”
35         step += fStackTotStack(record, RToM, MToR, mS, rS, mid, right); //“中”->“右”
36         step += fStackTotStack(record, MToR, RToM, rS, mS, right, mid); //“右”->“中”
37     }
38
39     return step;
40 }

原文地址:https://www.cnblogs.com/latup/p/9035267.html

时间: 2024-11-06 05:22:45

1.6 用栈来求解汉诺塔问题的相关文章

Java编程用栈来求解汉诺塔问题的代码实例(非递归)_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 [题目] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数. [解答] 上一篇用的是递归的方法解决这个问题,这里我们用栈来模拟汉诺塔的三个塔,也就是不用递归的方法 原理是这样的:修改后的汉诺塔问题不能让任何塔从左直接移动到右,也不能从右直接移动到左,而是要经过中间,也就是说,实际上

左神算法书籍《程序员代码面试指南》——1_06用栈来求解汉诺塔问题

[问题] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数.例如,当塔数为两层时,最上层的塔记为1,最下层的塔记为2,则打印:Move 1 from left to mid Move 1 from mid to right Move 2 from left to midMove 1 from right to mid Move 1 from mid to le

用栈来求解汉诺塔问题

当然.这是一个经典的递归问题~   想必来看这篇博文的同学对汉诺塔应该不会陌生了吧, 写这篇博还是有初衷的: 之前学数据结构的时候自己看书.也上网上查了很多资料,资料都比较散.而且描述的不是很清楚,对于当时刚刚 接触算法的我,要完全理解还是有一定难度.今天刚好有时间就整理了下思路.重写分析了一下之前的疑惑的地方. 没有透彻的地方便都豁然开朗了.所以迫不及待把我的想法记录下来,和大家分享. 如果你也是和之前的我一样对hanoi tower没能完全消化,或者刚刚接触汉诺塔,那希望我的这种理解方式能给

【算法题】06-用栈来解决汉诺塔问题

用栈来解决汉诺塔问题 题目 修改汉诺塔问题的游戏规则:限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动和最优移动总步数. 要求: 方法一:递归的方法 方法二:非递归的方法,用栈来模拟汉诺塔的三个塔 思路 方法一:递归的方法 首先,如果只剩最上层的塔需要移动,则有如下处理: 如果希望从左移动到右,打印Move 1 from left to right 如果希望从中移动到左,打印Move 1 from mid to left 如

递归求解汉诺塔问题

public void hanoi(int n) { if (n > 0) { func(n, "left", "mid", "right"); } } public void func(int n, String from, String mid, String to) { if (n == 1) { System.out.println("move from " + from + " to " +

汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归

汉诺塔(Tower of Hanoi)问题的求解--利用栈与递归 1. 汉诺塔问题的提法 汉诺塔问题是使用递归解决问题的经典范例. 传说婆罗门庙里有一个塔台,台上有3根标号为A.B.C的用钻石做成的柱子,在A柱上放着64个金盘,每一个都比下面的略小一点.把A柱上的金盘全部移到C柱上的那一天就是世界末日. 移动的条件是:一次只能移动一个金盘,移动过程中大金盘不能放在小金盘上面.庙里的僧人一直在移个不停,移动的最少总次数是264?1次,如果每秒移动一次的话,需要500亿年. 2. 求解汉诺塔问题的算

汉诺塔的非递归实现(栈)

汉诺塔的非递归实现(栈) 美国学者找的规律:若是偶数,将a.b.c顺时针排列,否则a.c.b排列,然后反复做: (1)最小盘顺时针移动一个 (2)那两个柱子将最小的移动了,空的话直接移 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标柱(标记为"c"),并保证每个移动符合汉诺塔问题的要求. 输入格式: 输入为一个正整数N,即起始柱上的盘数. 输出格式:

5-17 汉诺塔的非递归实现 (25分)

5-17 汉诺塔的非递归实现   (25分) 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标柱(标记为"c"),并保证每个移动符合汉诺塔问题的要求. 输入格式: 输入为一个正整数N,即起始柱上的盘数. 输出格式: 每个操作(移动)占一行,按柱1 -> 柱2的格式输出. 输入样例: 3 输出样例: a -> c a -> b c -&g

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

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