用VB编写Hanoi塔问题的动态演示程序
来源:优易学  2011-3-3 11:01:00   【优易学:中国教育考试门户网】   资料下载   IT书店

 1 引言
  在计算机算法设计中,使用递归技术往往使函数的定义和算法的描述简捷且易于理解。有些数据结构如二叉树等由于其本身固有的递归特性,特别适合用递归的形式来描述。还有一些问题,虽然其本身并没有明显的递归结构,但用递归技术来求解使设计出的算法简洁、易懂。因此深入掌握递归技术在算法设计过程中可以设计出更加有效的算法[1]。
  简单地说,递归就是用自己定义自己。使用递归方法构造算法的基本思路是:当求解规模为n的问题时,先将其分解成若干个规模较小的与原问题具有相同特征的子问题,并找出子问题与原问题之间的组合关系,最后根据具体问题构造出递归算法。
  递归算法的执行过程分“递推”和“回归”两个阶段。在递推阶段,把较复杂问题(如:规模为n)的求解推理至较原问题简单一些的问题(如规模为n-1)的求解;在回归阶段,把递推结束时所得到的解,逐级返回,依次得到稍复杂问题的解,最终得到原问题的解[2]。
  Hanoi塔问题是一个典型的适合于利用递归技术得到简洁算法的例子。Hanoi塔问题源自约19世纪末在欧洲出现的一种游戏,游戏中首先在一块铜板上放置三根柱子,在第一根柱子上自上而下、由小到大顺序串着64个盘子。游戏的目标是最后将所有盘子从第一根柱子上移到第三根柱子上,移动过程中可以用第二根柱子过渡。游戏规定一次只能移动一个盘子,并且任何时刻不允许大盘放在小盘的上面。
  现在就给出关于Hanoi塔问题的程序,让其将Hanoi塔问题的执行过程动态演示出来,以帮助读者加深理解递归技术。
  2 算法设计
  我们先利用递归技术对该问题进行算法设计。我们将三根柱子分别标号为A、B、C,目标是要将n个盘子从A柱子移动到C柱子。该问题可以设计如下的递归算法:
  第一步 将A柱子上n-1个盘子借助C柱子移动到B柱子上;
  第二步 将A柱子上剩余的第n个盘子移动到C柱子上;
  第三步 将B柱子上的n-1个盘子借助A柱子移动到C柱子上。
  对于第一步和第三步,我们又可以利用类似的方法继续将其求解过程设计为一个规模为n-1的Hanoi塔递归算法。
  3 递归算法动态演示过程的程序实现
  对于该算法的程序实现有两个关键的难点,其一是初始化部分如何将三根柱子和n个盘子按照问题要求在屏幕上绘制出来;其二是盘子移动过程的图形实现。
  3.1 form窗体设计及程序初始化
  首先在form窗体中添加三个命令按钮
  在开始执行Hanoi塔问题求解过程之前,需要将三根柱子绘制在屏幕上,还需要接收用户指定的盘子数及将盘子正确显示至A柱子上。在本程序中接收盘子数是利用InputBox函数接收保存至全局变量number中,用实心矩形代表盘子。
  这一部分的初始化工作在准备按钮的click事件过程中实现,其核心代码如下:
  Dim i As Integer
  '设置Form窗体属性
  Form1.Caption = "准备..."
  Form1.Cls
  '设置三个柱子的标记
  CurrentX = 4000
  CurrentY = hLevel + 61
  Form1.FontSize = 16
  Form1.ForeColor = vbRed
  Form1.FontBold = True
  Print "A"
  CurrentX = 8000
  CurrentY = hLevel + 61
  Print "B"
  CurrentX = 12000
  CurrentY = hLevel + 61
  Print "C"
  Form1.ForeColor = &H80000012
  Form1.FontSize = 10
  Form1.FontBold = False
  '画底线
  Form1.Line (0, hLevel)-(15360, hLevel + 100), vbGreen, BF
  '画三根柱子,A柱子的柱底坐标是(4000,10300)
  '纵坐标减10只是为了显示时看的效果更好一些,其实是不应该减的,减了后柱子底端纵坐标与底线上沿纵坐标就不一致了,但屏幕视觉是一致的
  Form1.Line (3995, 700)-(4005, hLevel - 10), vbBlack, BF
  Form1.Line (7995, 700)-(8005, hLevel - 10), vbBlack, BF
  Form1.Line (11995, 700)-(12008, hLevel - 10), vbBlack, BF
  number = Val(InputBox("请输入盘子数:", "输入数据", "3"))
  Form1.Caption = "共有" & number & "个盘子"
  '盘子宽400*i,高度200
  '相邻盘子之间的高度差设置为210,如果设置为相差200的话,当把上面一个盘子移走时两个盘子重叠部分无法重新修复
  For i = 1 To number
  Form1.Line ((4000 - (i * 400) / 2), (hLevel - (number + 1 - i) * 210))-((4000 + (i * 400) / 2), (hLevel - (number - i) * 210 - 10)), , BF
  Next i
  baseCoordinateY(1) = hLevel - number * 210
  baseCoordinateY(2) = hLevel
  baseCoordinateY(3) = hLevel

[1] [2] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训