汉诺塔动态演示程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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();/*手动控制的话就自己按键盘来控制*/ …演示效果如图: 百折书推荐阅读: