汉诺塔动态演示程序

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

汉诺塔递归算法C语言动态演示

汉诺塔递归算法具体演示功能:

①任意输入演示的个数;

②选择电脑自动演示和手动单步执行两种方式;

③若选择电脑自动演示请输入速度;

④屏幕上显示算法执行过程。

演示算法流程图:

汉诺塔模块编码:

汉诺塔问题是一个经典的递归问题。它给出的圆盘移动条件是:一次仅能移动一个盘,且不允许大

盘放在小盘的上面[1]。

算法演示思想[10]:设要解决的的汉诺塔共有N个圆盘,对A杆上的全部N个圆盘从小到大顺序编号,最小的圆盘为1号,次之为2号,依次类推,则最下面的圆盘的编号为N。

第一步:先将问题简化。假设A杆上只有一个圆盘,即汉诺塔只有一层N1,则只要将1号盘从

A杆上移到B杆上即可。

第二步:对於一个有N(N>1)个圆盘的汉诺塔,将N个圆盘分成两部分:上面的N-1个圆盘

和最下面的N号圆盘。

第三步:将“上面的N-1个圆盘”看成一个整体,为了解决N个圆盘的汉诺塔,可以按下面图示的

方式迳行操作:

1、将A杆上面的N-1个盘子,借助B杆,移到C杆上;

2、将A杆上剩余的N号盘子移到B杆上;

3、将C杆上的N-1个盘子,借助A杆,移到B杆上。

按照上面的想法,我们要演示的就是具体的移盘操作。

关键技术:画盘子、移盘、显示移盘步骤

实现步骤:

1、画盘子;

2、移盘、显示移盘步骤。

核心代码实现如下:

n 画盘子

首先定义一下盘子的结构:

struct H

{

int data[15];/*存放每个盘的代号*/

int top;/*每个塔的具体高度*/

}num[3];/*三个塔*/

接下来要定义一些标志变量来判断运行方式,比如:

int computer=1;/*自动控制与手动控制的标志*/

int speed=0;/*全局变量speed主要是演示过程的速度*/

然后要处理输入数据越界的情况,因为盘子个数过多,将很难实现,因此这里以0

界的话n当10处理。代码如下:

if(n<1||n>10)

n=10;/*越界的话n当10处理*/

下面来开始画盘子:

首先初始化三个地方塔的高度,代码如下:

for(i=0;i<3;i++)

num[i].top=-1;/*三个地方的高度开始都为-1*/

然后画一开始的塔座A上的盘子,代码如下:

for(i=0;i

{

num[0].top++;/*栈的高度加1*/

num[0].data[num[0].top]=i; /*最大的盘子代号为0,依次为1,2,…n-1*/ color=num[0].data[num[0].top]+1;/*盘子的颜色代码为栈顶盘子代号加1*/

setfillstyle(SOLID_FILL,color);

bar(100-(33-3*num[0].data[num[0].top]),400-20*i-8,100+

(33-3*num[0].data[num[0].top]),400-20*i+8); /*画矩形*/

}

setcolor(YELLOW);

outtextxy(180,450,"any key to continue");

settextstyle(0,0,2);

outtextxy(90,420,"A"); /*塔座标志*/

outtextxy(240,420,"B");

outtextxy(390,420,"C");

n 移盘、显示移盘步骤

接下来要做的解决移盘问题并显示移盘步骤,这个过程的代码如下:

int i;

char num1[3],num2[3];

sprintf(num1,"%c",x-32);/*将小写变成大写,并转换成字符串输出*/

sprintf(num2,"%c",y-32);

setfillstyle(SOLID_FILL,BLACK);/*把原来的地方移去涂黑*/

bar(0,0,640,60);

setcolor(RED);

outtextxy(150,30,num1);/*输出移动过程*/

outtextxy(200,30,"--->");

outtextxy(310,30,num2);

settextstyle(0,0,2);

setfillstyle(SOLID_FILL,BLACK);/*把原来的地方移去涂黑*/

bar(100+150*(x-97)-(33-3*num[x-97].data[num[x-97].top]),

400-20*num[x-97].top-8,100+150*(x-97)+(33-3*

num[x-97].data[num[x-97].top]),400-20*num[x-97].top+8);

num[y-97].top++;/*入栈,目标点的top加1*/

num[y-97].data[num[y-97].top]=num[x-97].data[num[x-97].top];/*在目标点盘子的代号与源点盘

子的代号相同*/

num[x-97].top--;/*出栈,原来地方的top减1*/

setfillstyle(SOLID_FILL,num[y-97].data[num[y-97].top]+1);/*盘子颜色代码是栈顶盘子代号加1*/ bar(100+150*(y-97)-(33-3*num[y-97].data[num[y-97].top]),

400-20*num[y-97].top-8,100+150*(y-97)+

(33-3*num[y-97].data[num[y-97].top]),400-20*num[y-97].top+8);

有个问题要注意的是怎么实现手动控制,其实用下面的代码就可以了:

if(computer)/*自动控制就用sleep延时函数*/

sleep(speed);/*延时函数*/

else

getch();/*手动控制的话就自己按键盘来控制*/

…演示效果如图:

百折书推荐阅读:

相关文档
最新文档