汉诺塔实现步骤

汉诺塔实现步骤
汉诺塔实现步骤

汉诺塔实现步骤

一、创建工作空间和应用(略)

二、创建结构体对象(str_disk)其中str_表示structure, disk就是圆盘.

三、创建用户对象(u_tower)

其中u_表示UserObject,选PB Object中的custom visual.

(1)操作界面

(2)设计控件

(3)控件名称

(4)部分控件不可见

(5)声明实例变量

其中roundrectangle irr_disk[14]定义栈空间(空栈)

int ii_count栈顶指针(栈内盘子数)

(6)编写constructor事件代码

作用:在空栈中放置栈元素(盘子)

//将14个圆角矩形控件对象加到数组中

//即初始化栈

//其结果数组元素irr_disk[1]-- irr_disk[14] 分别对应存放的是对象rr_1--rr_14。

int li_index

int li_array_limit

int li_control_index

int li_control_limit

string rr_name

drawobject ldo_temp

li_array_limit = upperbound (irr_disk[])//返回数组维界

li_control_limit = upperbound (control[])//

返回控件数组维界

//将控件数组里的隐藏矩形,放置在定义的实例对象数组中。

For li_control_index = 1 to li_control_limit //对控件数组的每个元素

ldo_temp = control[li_control_index]

rr_name= ldo_temp.classname()

li_index=dec(right(rr_name,len(rr_name)-3)) If li_index>=1 and li_index<= li_array_limit Then

irr_disk[li_index] = ldo_temp

End If

Next

思考:要将irr_disk[1]中放置rr_1对象,能不能这样处理

irr_disk[1]=rr_1?为什么?

(7)编写函数的操作方法

(8)编写adddisk函数(压栈)

//注意形式参数的引用方式

public subroutine adddisk (str_disk astr_disk);

//局部变量

int li_x//盘子的x坐标

int li_y//盘子的y坐标

//针上盘子数加1(栈顶指针加1)

ii_count++//u_tower成员

//only 14 rectangles were predefined.

If ii_count > 14 Then

Messagebox("Peg Error","Error only 14 disk are allowed")

ii_count --

Return

End If

//(图)计算盘子位置

//(式)计算盘子位置

li_y = r_base.y - ((irr_disk[ii_count].height+ 5)*ii_count) li_x = rr_pole.x + (rr_pole.width / 2) - (astr_disk.size / 2)

//盘子宽度和颜色由实参提供

irr_disk[ii_count].width = astr_disk.size

irr_disk[ii_count].fillcolor = astr_disk.color

irr_disk[ii_count].visible = true

irr_disk[ii_count].x = li_x

//(图)产生向下的效果

//(代码)产生向下的效果

irr_disk[ii_count].y = rr_pole.y + irr_disk[ii_count].height

do while irr_disk[ii_count].y < li_y

If irr_disk[ii_count].y + irr_disk[ii_count].height> li_y Then irr_disk[ii_count].y = li_y

Else

irr_disk[ii_count].y = irr_disk[ii_count].y&

+ irr_disk[ii_count].height

irr_disk[ii_count].visible = true

irr_disk[ii_count].show()

yield()

End If

loop

(9)编写removedisk函数(弹栈)

//注意形式参数的引用方式

public subroutine removedisk (ref str_disk as_disk);

//确保针上没有盘子时不做该操作

If ii_count <= 0 Then return

//产生向上的效果

do while irr_disk[ii_count].y > rr_pole.y + irr_disk[ii_count].height

If irr_disk[ii_count].y &

- (irr_disk[ii_count].height) <&

rr_pole.y &

+ irr_disk[ii_count].height Then

irr_disk[ii_count].y = rr_pole.y&

+ irr_disk[ii_count].height

Else

irr_disk[ii_count].y = irr_disk[ii_count].y&

- (irr_disk[ii_count].height)

irr_disk[ii_count].visible = true

irr_disk[ii_count].show()

yield()//放在循环中,发现信息消息会立即响应,否则等该程序执行完了,才会响应消息队列中的事件。

End If

loop

//盘子的大小和颜色有实参带出

as_disk.size = irr_disk[ii_count].width

as_disk.color = irr_disk[ii_count].fillcolor

//移去一个盘子,并对针上盘子数减1

//hide it

irr_disk[ii_count].visible = False

//one less disk now

ii_count --

(10) resetpeg 函数(置栈空)

//清除所有盘子

public subroutine resetpeg ();

str_disk lstr_disk

do while ii_count > 0

removedisk(lstr_disk)

loop

四、主窗口对象(W_towers_hanoi)

(1)原设计界面

(2)简化控件

(3)简化界面

(4)设计编辑掩码控件(EditMask)em_disks

(5)编写窗口函数wf_movedisk

//递归,将ai_disk个盘子从auo_startpeg针,借助于auo_midpeg,移到auo_endpeg针。

//一、形式参数

public subroutine wf_movedisk (int ai_disk, u_tower auo_startpeg, u_tower auo_midpeg, u_tower auo_endpeg);

//二、声明局部变量

str_disk lstr_disk

//该结构有两个成员:size和color

//三、仅一个盘子,直接移动,结束递归。

If ai_disk = 1 Then

auo_startpeg.removedisk(lstr_disk)

auo_endpeg.adddisk(lstr_disk)

//请注意局部变量lstr_disk的作用

Else

//四、大于一个盘子时,递归调用

wf_movedisk(ai_disk - 1, auo_startpeg, auo_endpeg, auo_midpeg)

wf_movedisk(1, auo_startpeg, u_tower, auo_endpeg)

wf_movedisk(ai_disk - 1, auo_midpeg, auo_startpeg, auo_endpeg)

End If

(6)cb_start 的Clicked代码

//一、声明局部变量

int li_disk// li_disk盘子数

int li_index//li_index盘子序号

int li_size

str_disk lstr_disk //结构变量。成员size和color。

long ll_rc

//二、取盘子数目

//how many disks used in this example

li_disk = Integer(em_disks.text)//从掩码控件(微调框)中读盘子数

If li_disk > 14 Or li_Disk < 1 Then

MessageBox("Peg Error", "Error! Only 14 disks are allowed.", Exclamation!)

Return

End If

//三、环境复位

//此按钮是双控按钮,在“开始”和“取消”间切换

//test if this is a start or cancel button

If this.text = "C&ancel" Then//表示汉诺塔在运行状态,此时该按钮的作用是取消运行。

ib_cancel = True//全局变量。

return

Else //否则,汉诺塔开始运行。

ib_cancel = False

this.text = "C&ancel"

End If

//reset all 3 pegs

// 3针复位,将三针上的盘子全部移走。

uo_peg_c.resetpeg()

uo_peg_b.resetpeg()

uo_peg_a.resetpeg()

//四、显示待移动的盘子

//第一针上创建n个盘子,至下而上,从大到小

//set up the first peg with the # of disks requested. Add the disk with a random color and the largest disk on the botton

For li_index = li_disk to 1 step - 1

lstr_disk.size = 170 + li_index * 60 //disk size即盘子的宽度变化,最小的230

lstr_disk.color = Rgb(rand(255),rand(255),rand(255)) //random disk color

uo_peg_a.adddisk(lstr_disk) //place the disk on the peg

Next

//disable buttons during the execution

//使“关闭”按钮失效

cb_close.enabled = false

//五、递归调用

//This starts the recursive routine

wf_movedisk(li_disk,uo_peg_a,uo_peg_b,uo_peg_c)//重点关注

//使“关闭”按钮有效

cb_close.enabled = true

//reset text back to "start"

this.text = "&Start"

(7)cb_close 的Clicked代码

Close(parent)

五、增加移动细节的记录

(1)主界面加listbox控件

控件名:lb_step

(2) listbox控件的属性

(3) 修改窗口函数wf_movedisk

原代码(灰):

//一、形式参数(在界面设置,不是代码部分)

public subroutine wf_movedisk (int ai_disk, u_tower auo_startpeg, u_tower auo_midpeg, u_tower auo_endpeg);

//二、声明局部变量

str_disk lstr_disk

//该结构有两个成员:size和color

//三、仅一个盘子,直接移动,结束递归。

If ai_disk = 1 Then

//增加移动的步骤序列

ii_step++//

//将步骤写入列表框

li_currow = lb_step.Additem(string(ii_step) + ". " +&

mid(auo_startpeg.classname(),4) + " --> " + mid(auo_endpeg.classname(),4))

lb_step.SetTop(li_currow)//列表框函数:

//滚动列表框使该列表项可见.

//别忘了,去添加实例变量ii_step,和局部变量li_currow

auo_startpeg.removedisk(lstr_disk)

auo_endpeg.adddisk(lstr_disk)

//请注意局部变量lstr_disk的作用

Else

//四、大于一个盘子时,递归调用

wf_movedisk(ai_disk - 1, auo_startpeg, auo_endpeg, auo_midpeg)

wf_movedisk(1, auo_startpeg, u_tower, auo_endpeg)

wf_movedisk(ai_disk - 1, auo_midpeg, auo_startpeg, auo_endpeg)

End If

六、增加单步移动控制窗口

(1)主界面加复选框checkbox控件(cbx_sstep)

(2)单步窗口对象(W_towers_single_step)

汉诺塔c++程序

void Hanoi(int platesCount, int from, int dest, int by) { if (platesCount==1) { printf( "Move the plate from %d to %d through %d" , from, dest, by); }else { Hanoi(platesCount -1, from, by, dest); Hanoi(1, from, dest, by); Hanoi(platesCount -1, by, dest, from); } } // Advance one step to solve Hanoi void HanoiDrawer::SolveNextStep() { int platesCount , source , destination , intermediate; if(listSavedState.size()==0) { this->Hanoi(this->iPlatesCount, HanoiDrawer::SOURCE , HanoiDrawer::DESTINATION, HanoiDrawer::INTERMEDIATE); } if(listSavedState.size() % 4 != 0 ) { return; } platesCount = listSavedState.front(); listSavedState.pop_front(); source = listSavedState.front(); listSavedState.pop_front(); destination = listSavedState.front(); listSavedState.pop_front(); intermediate = listSavedState.front(); listSavedState.pop_front();

用VB设计汉诺塔动画游戏

本栏目责任编辑:谢媛媛软件设计开发Computer Knowledge and Technology 电脑知识 与技术第5卷第30期(2009年10月)用VB 设计汉诺塔动画游戏 刘德强 (无锡职业技术学院,江苏无锡214024) 摘要:汉诺塔问题是程序设计教学中关于递归调用的经典案例。该文介绍了用VB 设计汉诺塔动画游戏程序的基本过程,其中重点介绍了用VB 的自定义数据类型和图形处理技术设计游戏步点状态记录和动画效果的方法。 关键词:VB ;汉诺塔;动画 中图分类号:TP311文献标识码:A 文章编号:1009-3044(2009)30-8460-03 The Designing of Hanoi Towers Animation Game by VB LIU De-qiang (Wuxi Institute of Technology,Wuxi 214024,China) Abstract:The Hanoi Towers is a typical case of recursive calls in programming teaching.This paper introduces the basic process of design -ing Hanoi Towers animation game by VB,focuses on recording game state between two steps and designing animation by self-defined data type and graph skill in VB. Key Words:VB;Hanoi;animation 汉诺塔问题源自印度的一个古老传说,传至现代演变成了汉诺塔游戏:有A 、B 、C 三个垂直杆和若干个大小各不相同的圆片。开始时圆片全部套在A 杆上,且从下至上圆片大小依次递减。要求借助B 杆,将圆片全部移到C 杆上,每次只能移动一片,并且整个过程中三个杆上的圆片都必须保持大的在下小的在上。游戏的难度由开始时放置在A 杆上圆片的个数进行控制。 1游戏步点状态记录设计 笔者设计的汉诺塔游戏程序主要包括演示和游戏两方面的功能。演示功能实现的是根据汉诺塔问题算法预先计算出的圆片移动顺序由计算机自行对圆片进行移动;而游戏功能是指计算机通过人机交互界面根据游戏者的实时操作顺序进行圆片的移动。图1是程序运行时界面。无论是演示还是游戏,计算机执行的基本动作元素是相同的,即圆片从一个杆上移动到另一个杆上,这一过程体现在程序设计中就是在新的位置对圆片图形进行重画,它与每个杆的步点状态密切相关。 步点状态是指每完成一步操作以后,开始下一步操作之前,一个杆上 的圆片数量及各圆片的位置和大小等多个特征综合构成的状态,是多个 数据的集合。将开始时圆片数记为n ,从初始状态圆片都在A 杆上,到终 止状态n 个圆片移到C 杆上,其间每次移动圆片,各杆的步点状态都会 发生变化。游戏进程中“记”住各杆的当前步点状态,是实现不断移动圆片 的关键。以要移动A 杆上的一个圆片到B 杆为例:要判断圆片根据规则 是否可以移动及圆片移动后放置在B 杆的什么位置(y 坐标),就必须知 道当前B 杆上最上端圆片的大小和B 杆上当前圆片数量,即B 杆的当前 步点状态。综合以上分析,游戏步点状态记录是程序设计中的要点。 鉴于描述步点状态需要多个数据,且数据间相互关联并构成整体,笔 者在设计中采用了自定义数据类型的方法,数据类型名称为circles ,所含 内容和定义格式如下: Type circles counts As integer r()As integer x As integer y()As integer End Type circles 类型中,数据成员counts 用于记录杆上实际圆片数,r 用于记录各圆片的半径,x 记录各圆片圆心的x 坐标,y 记录各圆片圆心的y 坐标。因为每次游戏设置的初始圆片数是不确定的且游戏进程中各杆都可能出现多个圆片,所以数据成员r 和y 定义为动态数组。 数据类型circles 定义以后,先使用该类型定义三个实例a 、b 、c ,分别代表A 、B 、C 三个杆的步点状态。语句如下: Dim a As circles ,b As circles ,c As circles 当初始圆片数量确定后(记为n),可使用下列语句对A 杆的步点状态a 进行初始化。 投稿日期:2009-08-22 作者简介:刘德强(1965-),江苏靖江人,无锡职业技术学院讲师。 图1运行界面ISSN 1009-3044Computer Knowledge and Technology 电脑知识与技术Vol.5,No.30,October 2009,pp.8460-8462E-mail:xsjl@https://www.360docs.net/doc/c414011884.html, https://www.360docs.net/doc/c414011884.html, Tel:+86-551-569096356909648460

汉诺塔 java 程序

汉诺塔java 程序 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class AutoMoveDisc extends JDialog implements ActionListener{ int amountOfDisc=3; TowerPoint [] pointA,pointB,pointC; char [] towerName; Container con; StringBuffer moveStep; JTextArea showStep; JButton bStart,bStop,bContinue,bClose; Timer time; int i=0,number=0; AutoMoveDisc(Container con){ setModal(true); setTitle("自动演示搬盘子过程"); this.con=con; moveStep=new StringBuffer(); time=new Timer(1000,this); time.setInitialDelay(10); showStep=new JTextArea(10,12); bStart=new JButton("演示"); bStop=new JButton("暂停"); bContinue=new JButton("继续"); bClose=new JButton("关闭"); bStart.addActionListener(this); bStop.addActionListener(this); bContinue.addActionListener(this); bClose.addActionListener(this); JPanel south=new JPanel(); south.setLayout(new FlowLayout()); south.add(bStart); south.add(bStop); south.add(bContinue); south.add(bClose); add(new JScrollPane(showStep),BorderLayout.CENTER); add(south,BorderLayout.SOUTH); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); towerName=new char[3]; addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ time.stop(); setVisible(false);

汉诺塔问题的三种实现

// test_project.cpp : 定义控制台应用程序的入口点。//汉诺塔问题的 // //递归实现 /*#include "stdafx.h" #include using namespace std; int count=0;//记录移动到了多少步 void Move(int n,char From,char To); void Hannoi(int n,char From, char Pass ,char To); //把圆盘从From,经过pass,移动到To int main() { int n_count=0; cout<<"请输入圆盘个数:"; cin>>n_count; Hannoi(n_count,'A','B','C'); } void Move(int n,char From,char To)

{ count++; cout<<"第"<

/*后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放A B C; 若n为奇数,按顺时针方向依次摆放A C B。 ()按顺时针方向把圆盘从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘在柱子A,则把它移动到B;若圆盘在柱子B,则把它移动到C;若圆盘在柱子C,则把它移动到A。 ()接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。 ()反复进行()()操作,最后就能按规定完成汉诺塔的移动。 所以结果非常简单,就是按照移动规则向一个方向移动金片: 如阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C 汉诺塔问题也是程序设计中的经典递归问题,下面我们将给出递归和非递归的不同实现源代码。*/ /*#include "stdafx.h" #include #include

汉诺塔程序设计报告

数据结构 学院:信息学院 班级:计科高职13-2 姓名:曲承玉 学号:201303014044

汉诺塔程序设计报告 一、题目 汉诺塔(Towers of Hanoi)问题 二、设计要求 1、在窗口中画出初始时塔和碟子的状态。 2、可以以自动或手动两种方式搬移碟子。 3、自动搬移可以通过定时器或多线程的方法,每一次移动的时间间隔可以自定,以人眼观察比较舒服为宜,每一次的移动过程如能实现动画最好。 4、定义塔的描述类和碟子的描述类。 5、在程序中,碟子的数目及每次移动的时间间隔可以通过对话框设置(也应该有默认值)。 6、支持暂停功和继续的功能(在自动搬移过程中可以暂停,并继续)。 7、暂停后,可以将当前的状态保存(碟子和塔的组合关系)。 8、可以从7中保存的文件中读出某个状态,并继续移动。 三、问题分析 1、已知有三个塔(1、 2、3)和n个从大到小的金碟子,初始状态时n个碟子按从大到小的次序从塔1的底部堆放至顶部。 2、要求把碟子都移动到塔2(按从大到小的次序从塔2的底部堆放至顶部)。 3、每次移动一个碟子。

4、任何时候、任何一个塔上都不能把大碟子放到小碟子的上面。 5、可以借助塔3。(图1-1) 图1-1 首先考虑a杆下面的盘子而非杆上最上面的盘子,于是任务变成了: 1、将上面的63个盘子移到b杆上; 2、将a杆上剩下的盘子移到c杆上; 3、将b杆上的全部盘子移到c杆上。 将这个过程继续下去,就是要先完成移动63个盘子、62个盘子、61个盘子....1个盘的工作。 四、算法选择 汉诺塔程序设计算法的实质就是递归递归思想的运用。现将其算法简述如下: 为了更清楚地描述算法,可以定义一个函数hanoi(n,a,b,c)。该函数的功能是:将n个盘子从塔a上借助塔b移动到塔c上。这样移动n 个盘子的工作就可以按照以下过程进行: 1) hanoi(n-1,a,c,b);//将n-1个金盘由a借助c移到b 2) 将最下面的金盘从a移动到c上;

汉诺塔问题

实验二知识表示方法 梵塔问题实验 1.实验目的 (1)了解知识表示相关技术; (2)掌握问题规约法或者状态空间法的分析方法。 2.实验内容(2个实验内容可以选择1个实现) (1)梵塔问题实验。熟悉和掌握问题规约法的原理、实质和规约过程;理解规约图的表示方法; (2)状态空间法实验。从前有一条河,河的左岸有m个传教士、m个野人和一艘最多可乘n人的小船。约定左岸,右岸和船上或者没有传教士,或者野人数量少于传教士,否则野人会把传教士吃掉。搜索一条可使所有的野人和传教士安全渡到右岸的方案。 3.实验报告要求 (1)简述实验原理及方法,并请给出程序设计流程图。 我们可以这样分析: (1)第一个和尚命令第二个和尚将63个盘子从A座移动到B座; (2)自己将底下最大的盘子从A移动到C; (3)再命令第二个和尚将63个盘子从B座移动到C;(4)第二个和尚命令第三个和尚重复(1)(2)(3);以此类推便可以实现。这明显是个递归的算法科技解决的问

题。 (2)源程序清单: #include #include using namespace std; void main() { void hanoi(int n,char x,char y,char z);

int n; printf("input the number of diskes\n"); scanf("%d",&n); hanoi(n,'A','B','C'); } void hanoi(int n,char p1,char p2,char p3) { if(1==n) cout<<"盘子从"<

汉诺塔游戏设计过程

兰州交通大学 数理与软件工程学院 课程设计报告 2011 ~2012学年第二学期 课程名称数据结构 设计题目汉诺塔游戏程序 班级信计1001班 小组成员张章、王欣、李贵生 报告者李贵生201005235 指导老师金静 2012年6月

一、实验目的: 通过此次C++实训,一方面加深了对C++语言的了解,而不只是单单的在课本中学到的那些理论。通过学生动手亲自编写,平时乏味的课程,变的生动有趣。平时在课堂上学到的东西可以自己动手编写,将其转化成一些实用的技能。另一方面,通过学生小组完成任务,提高团队意识,增加凝聚力,让同学们意识到团结就是力量,每个人都是重要的一份子。 二、题目:汉诺塔游戏程序 <1> 问题描述:在平面上有三个位置A、B、C,在A位置上有n 个大小不等的圆盘、小盘压在大盘上形成圆盘堆。要求将A位置的N个圆盘通过B位置移动到C位置上,并按同样的顺序叠放。 移动圆盘时必须遵循以下规则: 1.每一次只能移动一个圆盘 2.圆盘可以放在A、B、C任何一个塔座上 3.任何时刻都不能将大圆盘压在小圆盘上 <2> 基本要求: 圆盘的个数从键盘输入(如3-64等);用动画的形式在屏幕上显示盘的移动。 三、问题分析和任务定义 1、已知有三个塔(1、 2、3)和n个从大到小的金碟子,初始状态时n个碟子按从大到小的次序从塔1的底部堆放至顶部。 2、要求把碟子都移动到塔2(按从大到小的次序从塔2的底部堆

放至顶部)。 3、每次移动一个碟子。 4、任何时候、任何一个塔上都不能把大碟子放到小碟子的上面。 5、可以借助塔3。 先考虑a杆下面的盘子而非杆上最上面的盘子,于是任务变成了: 1、将上面的N个盘子移到b杆上; 2、将a杆上剩下的盘子移到c杆上; 3、将b杆上的全部盘子移到c杆上。 将这个过程继续下去,就是要先完成移动n个盘子、n-1个盘子、n-2个盘子....1个盘的工作。 四、课题介绍: 4.1 汉诺塔问题初始模型: 4.2 实现步骤: 为满足题目中盘子的移动问题,必须遵循的条件是:一次

汉诺塔程序实验报告

实验题目: Hanoi 塔问题 一、问题描述: 假设有三个分别命名为 A , B 和C 的塔座,在塔座 B 上插有n 个直径大小各不相同、从小到 大编号为1, 2,…,n 的圆盘。现要求将塔座 B 上的n 个圆盘移至塔座 A 上并仍按同样顺序 叠排,圆盘移动时必须遵守以下规则: (1 )每次只能移动一个圆盘; (2)圆盘可以插在 A , B 和C 中任一塔上; ( 3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。 要求: 用程序模拟上述问题解决办法,并输出移动的总次数, 圆盘的个数从键盘输入; 并想 办法计算出程序运行的时间。 二、 算法思路: 1 、建立数学模型: 这个问题可用递归法解决,并用数学归纳法又个别得出普遍解法: 假设塔座B 上有3个圆盘移动到塔座 A 上: (1) "将塔座B 上2个圆盘借助塔座 A 移动到塔座C 上; (2) "将塔座B 上1个圆盘移动到塔座 A 上; (3) "将塔座C 上2个圆盘借助塔座 B 移动到塔座A 上。 其中第 2步可以直接实现。第 1步又可用递归方法分解为: 1.1"将塔座B 上1个圆盘从塔座 1.2"将塔座B 上1个圆盘从塔座 1.3"将塔座A 上1个圆盘从塔座 第 3 步可以分解为: 3.1将塔座C 上1个圆盘从塔座 3.2将塔座C 上1个圆盘从塔座 3.3将塔座B 上1个圆盘从塔座 综上所述:可得到移动 3 个圆盘的步骤为 B->A,B->C, A->C, B->A, C->B, C->A, B->A, 2、算法设计: 将n 个圆盘由B 依次移到A , C 作为辅助塔座。当 n=1时,可以直接完成。否则,将塔 座B 顶上的n-1个圆盘借助塔座 A 移动到塔座C 上;然后将圆盘B 上第n 个圆盘移到塔 座A 上;最后将塔座 C 上的n-1个圆盘移到塔座 A 上,并用塔座B 作为辅助塔座。 三、原程序 #include #include #include int times = 0; void move(char a, char b) { printf("%c > %c \n", a,b); } void hno(int n,char a , char b, char c) { if (n==1) { move(a,c); times ++; } X 移动到塔座 A ; X 移动到塔座 C ; Z 移动到塔座 C 。 Y 移动到塔座 Y 移动到塔座 X 移动到塔座 B ; A ;

汉诺塔问题与递归思想教学设计

一、教学思想(包括教学背景、教学目标) 1、教学背景 本课程“递归算法”,属于《数据结构与算法》课程中“栈和队列”章节的重点和难点。数据结构与算法已经广泛应用于各行各业的数据存储和信息处理中,与人们的社会生活密不可分。该课程是计算机类相关专业核心骨干课程,处于计算机学科的核心地位,具有承上启下的作用。不仅成为全国高校计算机类硕士研究生入学的统考科目,还是各企业招聘信息类员工入职笔试的必考科目。数据结构与算法课程面向计算机科学与技术、软件工程等计算机类学生,属于专业基础课。 2、教学大纲 通过本课程的学习,主要培养学生以下几个方面的能力: 1)理解递归的算法; 2)掌握递归算法的实现要素; 3)掌握数值与非数值型递归的实现方法。 根据学生在学习基础和能力方面的差异性,将整个课程教学目标分成三个水平:合格水平(符合课标的最低要求),中等以上水平(符合课标的基本要求),优秀水平(符合或超出课标提出的最高要求)。具体如下表:

二、课程设计思路(包括教学方法、手段) “递归算法”课程以故事引入、案例驱动法、示范模仿、启发式等多元化教学方法,设计课程内容。具体的课堂内容如下所示:

1 1 2 3 3 7 4 15 5 31 count = 2n-1 思考:若移动速度为1个/秒,则需要 (264-1)/365/24/3600 >= 5849亿年。 四、总结和思考 总结: 对于阶乘这类数值型问题,可以表达成数学公式,然后从相应的公式入手推导,解决这类问题的递归定义,同时确定这个问题的边界条件,找到结束递归的条件。 对于汉诺塔这类非数值型问题,虽然很难找到数学公式表达,但可将问题进行分解,问题规模逐渐缩小,直至最小规模有直接解。 思考: 数值型问题:斐波那契数列的递归设计。 非数值型问题:八皇后问题的递归设计。阐述总结知识拓展 三、教学特色(总结教学特色和效果) 递归算法课程主要讨论递归设计的思想和实现。从阶乘实例入手,由浅入深,层层深入介绍了递归的设计要点和算法的实现。从汉诺塔问题,通过“边提问,边思考”的方式逐层深入地给出算法的分析和设计过程。通过故事引入、案例导入、实例演示、PPT展示、实现效果等“多元化教学方式”,努力扩展课堂教学主战场。加上逐步引导、问题驱动,启发学生对算法的理解,并用实例演示展示算法的分析过程,在编译环境下实现该算法,加深对算法实现过程的认识。 1、知识点的引入使用故事诱导法讲授 通过“老和尚讲故事”引入函数的递归调用,并通过“世界末日问题” 故事引入非数值型问题的递归分析,激发学习积极性,挖掘学生潜能。

汉诺塔问题实验报告

1.实验目的: 通过本实验,掌握复杂性问题的分析方法,了解汉诺塔游戏的时间复杂性和空间复杂性。 2.问题描述: 汉诺塔问题来自一个古老的传说:在世界刚被创建的时候有一座钻石宝塔(塔A),其上有64个金碟。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔B和塔C)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔A 上的碟子移动到塔C上去,其间借助于塔B的帮助。每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。当牧师们完成任务时,世界末日也就到了。 3.算法设计思想: 对于汉诺塔问题的求解,可以通过以下三个步骤实现: (1)将塔A上的n-1个碟子借助塔C先移到塔B上。 (2)把塔A上剩下的一个碟子移到塔C上。 (3)将n-1个碟子从塔B借助于塔A移到塔C上。 4.实验步骤: 1.用c++ 或c语言设计实现汉诺塔游戏; 2.让盘子数从2 开始到7进行实验,记录程序运行时间和递 归调用次数; 3.画出盘子数n和运行时间t 、递归调用次数m的关系图, 并进行分析。 5.代码设计: Hanio.cpp #include"stdafx.h" #include #include #include void hanoi(int n,char x,char y,char z) { if(n==1) { printf("从%c->搬到%c\n",x,z); } else { hanoi(n-1,x,z,y); printf("从%c->%c搬到\n",x,z); hanoi(n-1,y,x,z); }

汉诺塔问题的程序实现(hanoi塔)

问题重述: 有三根柱A、B、C,在柱A上有N块盘片,所有盘片都是大的在下面,小片能放在大片上面。现要将A上的N块盘片移到C柱上,每次只能移动一片,而且在同一根柱子上必须保持上面的盘片比下面的盘片小,输入任意的N,输出移动方法。 (注意:这是一个古老的传说,传说是如果把64个盘子由A柱移到了C柱的话,那么世界末日就到了,事实上如果要把64个盘子从A柱移到C柱的话,即使用计算机运算,也要计算数亿年,所以这个预言未必不是真实。) 【分析】 我们可以这样考虑,当n=1时,我们只要直接将A柱的盘子移到C柱,当n>1时,我们可以先把n-1个盘子由A柱通过C柱移到B柱,此时就可以把A柱剩下的最后一个盘子直接移到C柱,这样接下来只要把n-1个盘子通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表示将n个盘子从a通过b移到c 1.只要求输出搬运的次数 #include using namespace std; int m=0; void move() { m++; } void I(int n) { if(n==1) move(); else { I(n-1); move(); I(n-1); } } int main() { I(3); cout< using namespace std;

int fact(int n) { if(n==1) return(1); else return((2*fact(n-1)+1)); } int main() { cout< using namespace std; int m=0; void Move(int n,char x,char y) { cout<<"把"<>i; Hannoi(3,'a','b','c'); cout<<"总的搬运次数"<

汉诺塔课程设计报告

汉诺塔游戏 学院:理学院 班级:信科102班 组长:李万东 组员1:袁雪娇 组员2:张瑜 设计期限2012 年3月1开始 至2012年6月20 结束 课程设计题目:汉诺塔游戏 课程设计目的: 《JA V A程序设计》是计算机相关专业的必修专业基础课程,其实践性、应用性很强。实践教学环节是必不可少的一个重要环节。本课程的程序设计专题实际是计算机相关专业学生学习完《JA V A程序设计》课程后,进行的一次全面的综合训练,JA V A程序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较系统地掌握程序设计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行软件开发、并在实践应用方面打下一定基础。 随着社会的进步,我们用来娱乐的游戏世界也越来越丰富,越来越复杂。本程序的汉诺塔游戏不但包括了游戏最基本的功能,而且还能培养用户的逻辑思维能力,同时也给玩家提供了一定的娱乐空间。本游戏还包括一个自动演示搬移汉诺塔的功能,此功能能够帮助初次接触此游戏的用户了解此游戏的玩法。 课程设计理论: 本程序要求实现用图形界面,画出3个杆和若干个大小不一的矩形盘子,形成3个塔,分别为A塔,B塔,C塔,同时盘子数目可以人工设定。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动该盘子、释放鼠标来放置该盘子。用户在移动盘子的过程中,可以随时单击汉诺塔菜单栏的菜单中提供的按钮,重新开 1格式已调整,word版本可编辑.

始游戏,并且可以通过单击汉诺塔菜单栏的菜单提供的按钮,让程序自动完成把A塔上的盘子全部移动到C塔上,实现自动演示。 汉诺塔算法属于递归算法,该算法过程为: 假定要把n个盘子按题目规定由A杆借助B杆移动到C杆。 第一步:先把上面的n-1个盘子借助C杆放到B杆。 第二步:把第n个盘子从A杆直接移到C杆。 第三步:把B杆上的n-1个盘子借助A杆移到B杆。 概要设计: 1.课程设计内容: 有三个表示塔的对象,分别命名为A、B和C。A塔上有若干个盘子,盘子的大小不等,并按着大小顺序依次摆放在A塔上,大盘在下,小盘在上。用户可以用鼠标拖动盘子,把A塔上的盘子全部移动到另外两个塔中的任何一个塔上。要求每次只能移动一个盘子,在任何时候不允许大盘压在小盘的上面。用户也可以选择让程序自动演示。选择自动演示后,程序将以动画形式演示把A塔上的盘子全部移到C塔的过程。 2.课程设计功能: (1)设计GUI界面的汉诺塔。汉诺塔中有三个座,名字分别是A、B和C。初始状态是A座上有四个大小不等的盘子,这些盘子从座底到座顶按着大小顺序依次摆放在A座上。用户可以用鼠标选中盘子,然后通过拖动鼠标来移动该盘子、释放鼠标来放置该盘子。 (2)程序要求用户在移动盘子过程中,不允许把大盘子放在小盘子的上面,用户最终要完成的是把A座上的全部盘子移动到B座或C座上。 (3)用户可以通过单击汉诺塔菜单栏的菜单提供的按钮,让程序自动完成把A座上的盘子全部移动到B座或C座上。 (4)用户在移动盘子的过程中,可以随时单击汉诺塔菜单栏的菜单提供的按钮,重新开始游戏。 3. 2.

汉诺塔程序解读

hanoi塔程序如下: main() {hanoi(3,'A','B','C'); } hanoi(n,a,b,c) int n; char a,b,c; {if (n==1) printf("%c-->%c\n",a,c); else {hanoi (n-1,a,c,b); printf ("%c-->%c\n",a,c); hanoi (n-1,b,a,c);} } 运行结果: A-->C A-->B C-->B A-->C B-->A B-->C A-->C 问题: hanoi(n,a,b,c) int n; char a,b,c; {if (n==1) printf("%c-->%c\n",a,c); else {hanoi (n-1,a,c,b); printf ("%c-->%c\n",a,c); hanoi (n-1,b,a,c);} } 我给你详细解释下这个程序中的代码吧。我也是刚学,希望对你有用。可能有些不好之处,还希望谅解。 先说下这个问题的整体思想: 1,如果只有1个盘,那么就直接把这个盘从A移动到C上。

2,如果存在两个盘,那么先把第一个盘移动到B上,在把最下面一个盘移动到C上,在把B上的盘移动到C上。 3,这样,我们可以得出一个结论,如果存在N个盘,可以先把上面N-1个盘通过C 移动到B上,然后把第N个盘移动到C上,再把B上的N个盘通过A 移动到C上。 if (n==1) printf("%c-->%c\n",a,c); 这一句,表示只有1个盘子的时候,那么就是把第一个盘子直接移到第三个盘子上。 else {hanoi (n-1,a,c,b); 如果超过一个盘字,则需要先把N-1个盘子通过C 移动到B上。 printf ("%c-->%c\n",a,c); 把剩下的第N个盘,从A移动到C上。 hanoi (n-1,b,a,c);} 再把剩下的在B上的N-1个盘,通过A移动到C上。 这属于一个递归算法。 现在,N=3。 我们看下程序怎么运行的。 else {hanoi (n-1,a,c,b); printf ("%c-->%c\n",a,c); hanoi (n-1,b,a,c);} N=3,也就是开始程序会执行 hanoi (2,a,c,b);这句语句。 再看,2还是大于1,所以 程序会继续运行。注意,这里,为hanoi (2,a,c,b); C和B 换了位置。 hanoi (2,a,c,b); 我们把数字代入,得出。 根据N=2,C和B 互换。以及下面的代码,得出 ````````````````````````````````````````````````

汉诺塔探趣

“汉诺塔”问题探趣 洞头县实验小学 502班叶钫舟 指导老师洞头县实验小学陈素萍 一、问题的提出: 一位法国数学家曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。 尽管这个传说并不可信,但现在却成就了一种益智玩具━━“汉诺塔”(如图)的诞生。对下面这个8层汉诺塔,如何按以上要求将所有的圆盘从最左边的柱子上移到最右边的柱子上来呢?并如何保证移动的步子最少呢? 对这个富有挑战性的游戏,我非常有兴趣,于是我开始了研究! 二、研究过程: 1、简化器材,方便携带,随时演练,不断研究 “汉诺塔”游戏器材,体积较大,质量也大,不方便随身携带,因而也不能让我随时随地进行演练。 考虑到它最关键的是体现由小到大的一种排列,我用扑克牌同色的1(A),2,3,4,5,6,7,8来代替这个“汉诺塔”,平时演练,只要假想桌子上有左0、中1、右2三个档位即可,将这8张扑克牌从上到下按由小到大的顺序叠放在一起,放置在左边档位0处,然后将按游戏规则将它们依次全部移到最右边档位2处即可。 我把这种用扑克牌玩“汉诺塔”游戏称为“汉诺牌”,这样就很方便了!有时忘记了带扑克牌,我就用笔在纸上写下1~8这张8张“牌”,就可以玩了!

汉诺塔问题

XXXX大学信息学院 课程设计报告 教师签名:xxxxx

题目1实验报告 1.数据结构定义 因为该算法需要用到循环队列、堆和线性表,因此采用以下数据类型: typedef struct { QElemType *base; // 初始化的动态分配存储空间 int front; // 头指针,若队列不空,指向队列头元素 int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置 }SqQueue;//循环队列 typedef struct { int *elem; int length; int listsize; }SqList;//堆排序 2.算法说明 void HeapAdjust(int flag,SqList &H,int s,int m) void HeapSort(int flag,SqList &H)//对H进行堆排序; Status InitQueue(SqQueue &Q)//构造一个空队列Q,该队列预定义大小为MAXQSIZE; Status EnQueue(SqQueue &Q,QElemType e) //插入元素e为Q的新的队尾元素; Status DeQueue(SqQueue &Q, QElemType &e) // 若队列不空, 则删除Q的队头元素, 用e 返回其值, 并返回OK; 否则返回ERROR; Status GetHead(SqQueue Q, QElemType &e)// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR; Status QueueLength(SqQueue Q) // 返回Q的元素个数; Status QueueTraverse(SqQueue Q)// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR. 3.用户使用说明 运行程序,根据屏幕上的文字提示一步步操作。 4.个人测试结果(截图) 部分测试结果截图

汉诺塔问题C语言程序设计

三峡大学理学院2011级电信专业 《高级语言程序设计》课程设计 说明书 设计题目: 汉诺塔的搬移过程设计 班级:高级语言程序设计1 班 学号:2011142227 姓名:徐飞 完成日期:2012 年6月20日 1设计任务 设计题目:用递归法计算解决汉诺塔问题,并能够演示解决汉诺塔问题过; 要求:设计一个运用递归法计算解决汉诺塔问题C语言程序; 2 汉诺(Hanoi)塔问题的提出 古代有一个梵塔,塔内有A,B,C,3个座,座A上有64个大小不等的盘子,大的在下,小的在上(如下图)。有一个和尚想把这64个盘子从座A全部移到座C ,在移动过程中可以借用座A,座B或座C,但每次只允许移动一个盘子,并且不允许大盘放在小盘的上面。 3编程思路 首先,要找出递归的两个关键点,即: 递归终止条件:只有一个盘子时,可以移动。 递归表达式:要找出递归表达式,可以如下设想:

下面以3个盘子为例说明详细的移动过程: (1)将座A上的2个盘子移动到座B上; (2)将座A上的1个盘子移动到座C上; (3)将座B上的2个盘子移动到座C上; 上面第1步可用递归方法分解为: (1)将座A上的1个盘子从座A移动到座C上;

(2)将座A上的1个盘子从座A移动到座B上; (3)将座C上的1个盘子从座C移动到座B上; 第(3)步可用递归方法分解为: (1)将座B上的1个盘子从座B移动到座A上; (2)将座B上的1个盘子从座B移动到座C上; (3)将座B上的1个盘子从座A移动到座C上; 第(1)步操作可归纳为:将座A上的2个盘子借助座C移到座B; 第(3)步操作可归纳为:将座B上的2个盘子借助座A移到座C; 因此,将n个盘子从座A移到座C可以描述为: (1)将n-1个盘子从座A借助座C移到座B; (2)将剩下的一个盘子从座A移到座C; (3)将n-1个盘子从座B借助座A移到座C; 3系统操作流程图; 4.程序说明;

C#汉诺塔演示和代码

汉诺塔的演示界面: 本系统显示的是汉诺塔的演示效果,分别有播放,暂停,和停止,右边显示的是每一步的动作,同时记录操作次数,可以调节演示的速度。 汉诺塔界面代码: namespace honio4 { partial class Form1 { ///

/// 必需的设计器变量。 /// https://www.360docs.net/doc/c414011884.html,ponentModel.IContainer components = null; /// /// 清理所有正在使用的资源。 /// /// 如果应释放托管资源,为true;否则为false。 protected override void Dispose(bool disposing) { if (disposing && (components != null)) {

components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 ///

/// 设计器支持所需的方法- 不要 /// 使用代码编辑器修改此方法的内容。 /// private void InitializeComponent() { https://www.360docs.net/doc/c414011884.html,ponents = new https://www.360docs.net/doc/c414011884.html,ponentModel.Container(); this.panel1 = new System.Windows.Forms.Panel(); this.panel2 = new System.Windows.Forms.Panel(); this.panel3 = new System.Windows.Forms.Panel(); https://www.360docs.net/doc/c414011884.html,bel1 = new https://www.360docs.net/doc/c414011884.html,bel(); this.udLevels = new System.Windows.Forms.NumericUpDown(); this.btnStart = new System.Windows.Forms.Button(); this.btnPause = new System.Windows.Forms.Button(); this.btnStop = new System.Windows.Forms.Button(); https://www.360docs.net/doc/c414011884.html,bel2 = new https://www.360docs.net/doc/c414011884.html,bel(); this.trackSpeed = new System.Windows.Forms.TrackBar(); https://www.360docs.net/doc/c414011884.html,bel3 = new https://www.360docs.net/doc/c414011884.html,bel(); this.progress = new System.Windows.Forms.ProgressBar(); this.tmrPlay = new System.Windows.Forms.Timer(https://www.360docs.net/doc/c414011884.html,ponents); this.listBox1 = new System.Windows.Forms.ListBox(); https://www.360docs.net/doc/c414011884.html,bel4 = new https://www.360docs.net/doc/c414011884.html,bel(); https://www.360docs.net/doc/c414011884.html,bel5 = new https://www.360docs.net/doc/c414011884.html,bel(); https://www.360docs.net/doc/c414011884.html,bel6 = new https://www.360docs.net/doc/c414011884.html,bel(); https://www.360docs.net/doc/c414011884.html,bel7 = new https://www.360docs.net/doc/c414011884.html,bel(); https://www.360docs.net/doc/c414011884.html,bel8 = new https://www.360docs.net/doc/c414011884.html,bel(); ((https://www.360docs.net/doc/c414011884.html,ponentModel.ISupportInitialize)(this.udLevels)).BeginInit(); ((https://www.360docs.net/doc/c414011884.html,ponentModel.ISupportInitialize)(this.trackSpeed)).BeginInit(); this.SuspendLayout(); // // panel1 // this.panel1.Location = new System.Drawing.Point(16, 16); https://www.360docs.net/doc/c414011884.html, = "panel1"; this.panel1.Size = new System.Drawing.Size(96, 144); this.panel1.TabIndex = 7; this.panel1.Paint += new

相关文档
最新文档