using System;
public class Hanoi public Hanoi(int SourceNumber) public void HanoiMove(int FromWhere,int ToWhere, int n) for (int i = 1; i <= 3; i++) this.HanoiMove(FromWhere,ToWhere,n-1); for (int i = 1; i <= 3; i++) for (int i = 1; i <= 3; i++) return; } |
马牛的C#学习(第六天)-实践!用C#解决汉诺塔问题
最新推荐文章于 2024-09-26 13:18:11 发布
汉诺塔问题是学习递归的一个经典问题,几乎学计算机基础时每一次讲到递归,都有提到汉诺塔问题。这个学期上数据结构的课,老师叫我们写个程序解决汉诺塔问题,用什么语言实现都可以。正好,我最近在学C#,就用C#实现一下吧,练习一下C#~
首先我们看看汉诺塔问题的描述:
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
我们应该用递归的思想来解决这个问题。为什么会想到递归呢?
我们由四个盘子的情况可以看到,开始先想办法将上面三个盘子移到free上(从左到右的三个柱子分别记作source free target),然后再将SOURCE上的那个最大的盘子移到TARGET上,再想办法将FREE上的三个盘子移到TARGET上。考虑5个盘子的情况,先想办法将4个盘子移到FREE上,再将最大的盘子从SOURCE移到TARGET上,再将FREE上的四个盘子移到TARGET上。以此类推,考虑N个盘子时的情况,先想办法将N-1个盘子移到FREE上,再将最大的盘子从SOURCE移到TARGET上,然后想办法将FREE上的N-1个盘子移到TARGET上。
这正好符合了递归由结果推向前提、由后往前推的思想。
我们现在来看看为什么不用由前向后推的方法。我们看看图三(共三个盘子)中的第四种情况,这时是将最小的两个盘子单独放在FREE上。再来考虑一下共四个盘子时的情况,想想可以知道,到某一步时,只有最小的两个盘子在TARGET上。共有五个盘子时,又是不同。推想可知,总盘数不同时,最小的T个盘子所单独在的位置是不同的。这样,如果用穷举法来穷举总盘数为N时的所有情况,效率太低也不易实现。
所以要用递归!
先来分析一下问题,我们可以用数学归纳法的思想来考虑这个问题,先看看4个以下盘子的解决方案。
图一
图二
图三
图四
考虑问题时可以从一个盘开始,在明白已知盘数时的解决办法后,将其抽象化,考虑盘数为N时的解决方法。
可以先用递归的经典图(如下)试着写出算法,错了不怕,可以一步步修改。
C#代码如下: