#include <stdio.h>
//汉诺塔x层塔从A塔整体搬到C塔,中间临时B塔。
//x层塔是从大到小往上叠放。每次移动只能移动一层塔。并且在移动过程中必须保证小层在上边
//借助B塔可以将x层塔全部从A搬到C上,并且符合要求(在移动过程中大的那块在下边,小的那块在上边卖迟)
int main()
{
void tower(int x,char a,char b,char c) //声明函数
int x=5,a='A',b='B',c='C' //x表示有5层塔,具体要多少层自己修改这个值。abc分别表示ABC塔。
tower(x,a,b,c) //x层塔从a移动到c的全过程,主程序只有这条有效语句
return 0
}
//以下是tower函数的定义
//参数解析:x层塔放在a上,b是中间塔,c是目标塔。即x层塔要从a搬到c上。
//此函数实现x层塔从a整体转移到c上。以及这个过程是怎么搬的全部过程。
void tower(int x,char a,char b,char c)
{
if(x==1)printf("将%d从%c放到%c\n",x,a,c) //只有1层塔时,直接从a搬到c上。
else //不止1层塔,则先将x-1层塔从a按照规律搬到b上,再将最后一块从a搬到c上,最后再将b上的x-1层塔按没祥照规律搬到c上。
{
tower(x-1,a,c,b) //先将x-1层塔从a按照规律搬到b上,注意参数b放在最后,因为放在最后的参数是准备搬过去的目标塔。
printf("将%d从%c放到%c\n",x,a,c) //将最后一块从a搬到c上
tower(x-1,b,a,c) //最后再将b上的x-1层塔按照规律搬到c上,注意参数b放在开头,因为x-1层是要从b上搬过去的。
}
}
递归算法是我前些天写的,非递归是刚才找的,里面含递归和非递归。\x0d\x0a递归算法:\x0d\x0a#include \x0d\x0a//递归求汉诺塔问题\x0d\x0avoid hanoi(int n, char A, char B, char C, int *time)\x0d\x0a{\x0d\x0aif (n>=1)\x0d\x0a{\x0d\x0a hanoi(n-1, A, C, B, time)\x0d\x0a move(A, C)\x0d\x0a (*time)++\x0d\x0a hanoi(n-1, B, A, C, time)\x0d\x0a}\x0d\x0a}\x0d\x0a//打印出每一步的路径\x0d\x0avoid move(char a, char c)\x0d\x0a{\x0d\x0aprintf(" %c-->%c\n", a, c)\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint n, time = 0\x0d\x0aprintf("请输入汉诺塔的盘数:")\x0d\x0ascanf("%d", &n)\x0d\x0aprintf("%d个盘的汉诺塔移动方法是:", n)\x0d\x0aprintf("\n")\x0d\x0ahanoi(n, 'A', 'B', 'C', &time)\x0d\x0aprintf("移动了%d次\n", time)\x0d\x0asystem("pause")\x0d\x0areturn 0\x0d\x0a}\x0d\x0a\x0d\x0a非递裤做归算法:\x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXSTACK 10 /* 栈的最大深度 */\x0d\x0a\x0d\x0aint c = 1/* 一个全局变量,表示目前移动的步数 */\x0d\x0a\x0d\x0astruct hanoi { /* 存储汉诺塔的结构,包括盘的数目和三个盘的名称 */\x0d\x0aint n\x0d\x0achar x, y, z\x0d\x0a}\x0d\x0a\x0d\x0avoid move(char x, int n, char y) /* 移动函数,表示把某个盘从某根针移动到另一根针 */\x0d\x0a{\x0d\x0aprintf("%d->%d from %c ->%c\n", c++, n, x, y)\x0d\x0a}\x0d\x0a\x0d\x0avoid hanoi(int n, char x, char y, char z) /* 汉诺塔的递归算法 */\x0d\x0a{\x0d\x0aif (1 == n)\x0d\x0amove(x, 1, z)\x0d\x0aelse {\x0d\x0ahanoi(n - 1, x, z, y)\x0d\x0amove(x, n, z)\x0d\x0ahanoi(n - 1, y, x, z)\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0avoid push(struct hanoi *p, int top, char x, char y, char z,int n)\x0d\x0a{\x0d\x0ap[top+1].n = n - 1\x0d\x0ap[top+1].x = x\x0d\x0ap[top+1].y = y\x0d\x0ap[top+1].z = z\x0d\x0a}\x0d\x0a\x0d\x0avoid unreverse_hanoi(struct hanoi *p) /* 汉诺塔的非递归算法 */\x0d\x0a{\x0d\x0aint top = 0\x0d\x0a\x0d\x0awhile (top >胡闷衡= 0) {\x0d\x0awhile (p[top].n >1) { /* 向左走到尽头 */\x0d\x0a push(p, top, p[top].x, p[top].z, p[top].y, p[top].n)\x0d\罩衫x0a top++\x0d\x0a}\x0d\x0aif (p[top].n == 1) { /* 叶子结点 */\x0d\x0a move(p[top].x, 1, p[top].z)\x0d\x0a top--\x0d\x0a}\x0d\x0aif (top >= 0) { /* 向右走一步 */\x0d\x0a move(p[top].x, p[top].n, p[top].z)\x0d\x0a top--\x0d\x0a push(p, top, p[top+1].y, p[top+1].x, p[top+1].z, p[top+1].n)\x0d\x0a top++\x0d\x0a}\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint i\x0d\x0aprintf("递归:\n")\x0d\x0ahanoi(3, 'x', 'y', 'z')\x0d\x0aprintf("非递归:\n")\x0d\x0astruct hanoi p[MAXSTACK]\x0d\x0ac = 1\x0d\x0ap[0].n = 3\x0d\x0ap[0].x = 'x', p[0].y = 'y', p[0].z = 'z'\x0d\x0aunreverse_hanoi(p)\x0d\x0a\x0d\x0areturn 0\x0d\x0a}/*5. 源程序*//********hanoi.c*********/
#include <graphics.h>
struct H
{
int data[15]/*存放每个盘的代号*/
int top/*每个塔的具体高度*/
}num[3]/*三个塔*/
void move(char x,char y,struct H num[3])/*移动的具体过程*/
void hanoi(char x,char y,char z,int n,struct H num[3])/*递归*/
void Init(void)/*初始化*/
void Close(void)/*图形关闭*/
int computer=1/*自动控制与手动控制的标志*/
int speed=0/*全局变量speed主要是演示过程的速度*/
void main(void)
{
Init()/*初始状态*/
Close()/*图形关闭*/
exit(0)
}
void Init(void)/*初始化*/
{
int gd=DETECT,gm
int i,n,color
clrscr()
printf("please input n(n<=10): ")/*输入要演示的盘子数*/
scanf("%d",&n)
printf("Please input 1 or 2:\n1.computer 2.people\n")
scanf("%d",&i)
if(i==2)/*选择手动控制标志为0*/
computer=0
if(n<1||n>10)
n=10/*越界的话n当10处理*/
if(computer)/*如果是自动控制的话输入速度*/
{
printf("please input speed: ")/*输入速度*/
scanf("%d",&speed)
}
initgraph(&gd,&gm,"c:\早碰\tc")
cleardevice()
for(i=0i<3i++)
num[i].top=-1/*三个地陆散谈方的高度开始都为-1*/
for(i=0i<ni++)/*画一开始的塔座A上的盘子*/
{
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")
getch()/*接收字符后就执行递归 *** 掘厅作*/
hanoi('a','b','c',n,num)
}
void move(char x,char y,struct H num[3])/*移动的具体过程*/
{
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)/*自动控制就用delay*/
delay(speed)/*延时函数*/
else
getch()/*手动控制的话就自己按键盘来控制*/
}
void hanoi(char one,char two,char three,int n,struct H num[3])/*递归n为盘子数,num为堆栈*/
{
if(n==1)
move(one,three,num)/*如果盘子为1,将这个盘子从塔座A移动到塔座C*/
else
{
hanoi(one,three,two,n-1,num)/*将塔座A的前n-1个盘子移到塔座B*/
move(one,three,num)/*将塔座A的第n个盘子移到塔座C*/
hanoi(two,one,three,n-1,num)/*将塔座B的n-1个盘子移到塔座C*/
}
}
void Close(void)/*图形关闭*/
{
getch()
closegraph()
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)