# 数据结构课程设计大曝光(2) **注:转发请注明出处,以免老师误以为本人抄袭……** [TOC] # 课程设计二 HANOI问题的求解演示 ## 一、实习目的和任务: ### 【问题描述】 设计一个程序,演示HANOI问题的实现过程。 ### 【基本要求】 - (1)用户可手工移动圆盘实现求解。 - (2)用户可让计算机演示求解过程。 - (3)用非递归算法实现。 ## 二、概要设计: **设计思路:用栈和循环共同实现汉诺塔非递归求解** ### 1.栈的顺序结构实现: #### ADT SqStack { 数据对象:D={ai|ai∈CharSet,i=1,2,……,n,n≥0} 数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,……,n} 基本操作: #### Status InitStack(SqStack &S) 操作结果:完成初始化并构造一个空栈S #### void DestroyStack(SqStack &S) 初始条件:栈S已存在 操作结果:销毁栈S #### Status ClearStack(SqStack &S) 初始条件:栈S已存在 操作结果:把S置为空栈 #### Status StackEmpty(SqStack S) 初始条件:栈S已存在 操作结果:若栈S为空栈,则返回TRUE,否则返回FALSE #### int StackLenth(SqStack &S) 初始条件:栈S已存在 操作结果:返回S的元素个数,即栈的长度 #### Status StackTraverse(SqStack &S,Status(*visit)(SElemType &e)) 初始条件:栈S已存在 操作结果:从栈底到栈顶依次对栈中每一个元素调用函数visit(),一旦visit()失败,则返回ERROR #### Status GetTop(SqStack S,SElemType &e) 初始条件:栈S已存在 操作结果:若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR #### Status Push(SqStack &S,SElemType e) 初始条件:栈S已存在 操作结果:插入元素e为新的栈顶元素 #### Status Pop(SqStack &S,SElemType &e) 初始条件:栈S已存在 操作结果:若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR #### Status PutElem(SElemType &e) 操作结果:输出元素e,用作栈的遍历函数 #### void PrintStack(SqStack &S) 初始条件:栈S已存在 操作结果:从栈底依次显示栈中的所有元素,不对栈作任何修改 #### }ADT SqStack ### 2、关于汉诺塔的求解 - struct FState-------------------------------------------------------------保存函数状态的结构体 - void InitQuestion(int n,SqStack &a)---------------------------------对问题进行初始设置,即将圆盘依次摆在A座上,运行前要保证a为空栈 - int Success(int n,SqStack &c)-----------------------------------------判断问题是否已被解决 - Status MovePlate(SqStack &a,SqStack &b)------------------------将a的顶层盘子移动到b上,成功返回OK,失败(a中已经没有盘子或者不符合移动条件)返回ERROR - void ShowCurrent(SqStack &a,SqStack &b,SqStack &c)---------输出当前汉诺塔状态 - void MoveCMDTrans(char *s,SqStack &a,SqStack &b,SqStack &c,int &step)----------------------------解释执行移动圆盘命令 - void move(char *s,char x,int n,char z,int step)-----------------------与汉诺塔递归求解相关的函数,显示移动步骤并生成移动盘子命令 - void hanoi(int n,char x,char y,char z,SqStack &a,SqStack &b,SqStack &c,int &step)-------------------汉诺塔的递归求解过程 - void letSt(FState *st,int n,char a,char b,char c)----------------------给状态赋值 - void makeStSpace(FState *(&st))-------------------------------------申请保存一个状态的空间 - void SolveStep(SqStack &a,SqStack &b,SqStack &c,int &step,int n)----------------------------------------计算机求解解决汉诺塔问题的过程(非递归求解) - Status ShowSolve(int n,char d)----------------------------------------计算机自动演示求解过程,演示完成后不影响用户解决问题进程 - void InputNO(int &n)-----------------------------------------------------用户输入汉诺塔高度 ### 3、用户交互的实现: - char *c1="aAbBcC";char *c2="HhTtSsDdRrNnXx"; ----------------定义用户可以使用的命令 - instr(char c,char *str)------------------------判断c是否在str中,用于命令判断 - int isCmd(char *cmd) ------------------------判断是否为可识别的命令,即判断cmd与c1、c2的关系 - void Pause() ----------------------------------暂停并按任意键继续 - void Help() ------------------------------------输出命令帮助 - void openScreen()-----------------------------输出开始界面 - void Goodbye(SqList &sl1,SqList &sl2,SqList &sl3)----------------退出界面并完成销毁工作 - void CMDtran(char c,SqList &sl1,SqList &sl2,SqList &sl3)--------解释命令并执行 - void InputCMD(char * s) --------------------命令输入 - void CMDTrans(int &step,int &n,char *s,SqStack &a,SqStack &b,SqStack &c)----------------------------将字符串命令解释执行并输出执行后的汉诺塔状态 ## 三、程序代码: ```C /******************************************** HANOI问题的求解演示。 【问题描述】 设计一个程序,演示HANOI问题的实现过程。 【基本要求】 (1)用户可手工移动圆盘实现求解。 (2)用户可让计算机演示求解过程。 (3)用非递归算法实现。 ******************************************/ #include "stdio.h"//printf() #include "stdlib.h"//malloc(),system() #include "conio.h"//getch() #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //Status 是函数的类型,其值是函数结果状态代码 typedef int Status; typedef int SElemType; //----------------------------------栈的顺序存储结构 定义 开始-------------------- #define STACK_INIT_SIZE 100//存储空间初始分配量 #define STACKINCREMENT 100//存储空间分配增量 typedef struct{ SElemType * base;//在栈构造之前和销毁之后,base的值为NULL SElemType *top;//栈顶指针 int stacksize;//当前已分配的存储空间,以元素为单位 }SqStack; //---------------------------------栈的顺序存储结构 定义 结束-------------------- //-----------------栈的顺序存储结构 基本操作的实现 开始---------------------------------- Status InitStack(SqStack &S){ //构造一个空栈S S.base=(SElemType *)malloc(STACK_INIT_SIZE *sizeof(SElemType)); if(!S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; }//InitStack Status ClearStack(SqStack &S)//把S置为空栈 { if(S.top=S.base) return OK; else return ERROR; }//ClearStack Status StackEmpty(SqStack S) {//若栈S为空栈,则返回TRUE,否则返回FALSE if(S.top==S.base) return TRUE; else return FALSE; }//StackEmpty int StackLenth(SqStack &S) {//返回S的元素个数,即栈的长度 return S.top-S.base; }//StackLenth Status StackTraverse(SqStack &S,Status(*visit)(SElemType &e)) {//从栈底到栈顶依次对栈中每一个元素调用函数visit(),一旦visit()失败,则返回ERROR SElemType *p; for(p=S.base;p!=S.top;p++) { if(!visit( (*p) ))return ERROR; }//for return OK; }//StackTraverse Status GetTop(SqStack S,SElemType &e){ //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR if(S.top==S.base)return ERROR; e=*(S.top-1); return OK; }//GetTop Status Push(SqStack &S,SElemType e){ //插入元素e为新的栈顶元素 if(S.top-S.base>=S.stacksize){ //栈满,追加存储空间 S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType)); if(!S.base)exit(OVERFLOW);//存储分配失败 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; }//if *S.top++ =e; return OK; }//Push Status Pop(SqStack &S,SElemType &e) {//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR if(S.top==S.base) return ERROR; e=* --S.top; return OK; }//Pop void DestroyStack(SqStack &S)//销毁栈S { if(!S.base)free(S.base); S.base=NULL; S.top=NULL; S.stacksize=0; }//DestroyStack Status PutElem(SElemType &e)//输出元素e { if(putchar(e)) return OK; else return ERROR; }//PutElem void PrintStack(SqStack &S) {//从栈底依次显示栈中的所有元素,不对栈作任何修改 StackTraverse(S,PutElem); putch('\n'); }//PrintStack //------------------栈的顺序存储结构 基本操作的实现 结束---------------------------------- //--------------------------------关于汉诺塔的函数 开始------------------------------- typedef struct{ int n; SElemType x; SElemType y; SElemType z; }FState;//保存函数状态的结构体 void Pause() {//按任意键继续 printf("\n按任意键继续……\n"); getch(); }//Pause void InitQuestion(int n,SqStack &a) {//对问题进行初始设置,即将圆盘依次摆在A座上,运行前要保证a为空栈 int i;//循环变量 for(i=48+n;i>=49;i--) Push(a,i); }//InitQuestion int Success(int n,SqStack &c) {//判断问题是否已被解决 int i;//循环变量 if(StackLenth(c)!=n) return FALSE; else { for(i=0;i<n;i++) if(c.base[i]!=48+n-i) return FALSE; return TRUE; }//else return TRUE; }//Success Status MovePlate(SqStack &a,SqStack &b) {//将a的顶层盘子移动到b上,成功返回OK,失败(a中已经没有盘子或者不符合移动条件)返回ERROR SElemType e,f; if( (! GetTop(a,e) ) || (GetTop(b,f) && e>f) ) return ERROR; else { Pop(a,e); Push(b,e); }//else return OK; }//MovePlate void ShowCurrent(SqStack &a,SqStack &b,SqStack &c) {//输出当前汉诺塔状态 printf("当前汉诺塔状态:\n"); printf("A:");PrintStack(a); printf("B:");PrintStack(b); printf("C:");PrintStack(c); printf("\n"); }//ShowCurrent void MoveCMDTrans(char *s,SqStack &a,SqStack &b,SqStack &c,int &step) {//解释执行移动圆盘命令 SqStack *m,*n; if(s[3]=='\0'){ switch(s[0]) { case 'a'://Pass Through case 'A': m=&a; break; case 'b'://Pass Through case 'B': m=&b; break; case 'c'://Pass Through case 'C': m=&c; break; default: printf("无法识别的命令……,请重新输入\n"); break; }//switch(s[0]) switch(s[2]) { case 'a'://Pass Through case 'A': n=&a; break; case 'b'://Pass Through case 'B': n=&b; break; case 'c'://Pass Through case 'C': n=&c; break; default: printf("无法识别的命令……,请重新输入\n"); break; }//switch(s[2]) if(MovePlate((*m),(*n))){ printf("从%c移动到%c,移动成功!\n",s[0],s[2]); step++; }//if(MovePlate) else printf("从%c移动到%c,移动失败……\n",s[0],s[2]); }//if(s[3]) else { printf("无法识别的命令……,请重新输入\n"); }//else(s[3]) ShowCurrent(a,b,c);//输出当前汉诺塔状态 }//MoveCMDTrans void move(char *s,char x,int n,char z,int step) {//与汉诺塔递归求解相关的函数,显示移动步骤并生成移动盘子命令 printf("第%d步:将第%d个盘子从%c座移动到%c座\n",step,n,x,z); s[0]=x; s[1]='-'; s[2]=z; s[3]='\0'; printf("执行命令:%s\n",s); }//move void hanoi(int n,char x,char y,char z,SqStack &a,SqStack &b,SqStack &c,int &step) {//汉诺塔的递归求解过程 char s[4];//保存自动生成的命令 if(n==1) { move(s,x,1,z,step); MoveCMDTrans(s,a,b,c,step);//解释执行移动圆盘命令 }//if else { hanoi(n-1,x,z,y,a,b,c,step); move(s,x,n,z,step);//显示移动步骤并生成移动盘子命令 MoveCMDTrans(s,a,b,c,step);//解释执行移动圆盘命令 hanoi(n-1,y,x,z,a,b,c,step); }//else }//hanoi void letSt(FState *st,int n,char a,char b,char c) {//给状态赋值 st->n=n; st->x=a; st->y=b; st->z=c; } void makeStSpace(FState *(&st)) {//申请保存一个状态的空间 st=(FState *)malloc(sizeof(FState)); if(!st)exit(OVERFLOW); } void SolveStep(SqStack &a,SqStack &b,SqStack &c,int &step,int n) {//计算机求解解决汉诺塔问题的过程(非递归求解) SqStack FuncStack;//FuncStack为保存函数状态的栈 InitStack(FuncStack);//对FuncStack进行初始化 char s[4];//用于保存计算机演示过程中生成的命令字串 //相当于hanoi(n,'a','b','c') FState * st1,* st2; makeStSpace(st1);//申请保存一个状态的空间 letSt(st1,n,'a','b','c');//初始赋值 Push(FuncStack,(int)st1);//将状态压栈 while(!StackEmpty(FuncStack)) { //相当于hanoi(n-1,x,z,y) while(GetTop(FuncStack,(int &)st1)&&(st1->n)!=1){ makeStSpace(st2);//申请保存一个状态的空间 letSt(st2,st1->n-1,st1->x,st1->z,st1->y);//给此状态赋值 Push(FuncStack,(int)st2);//将状态压栈 } //相当于if(n==1){……} Pop(FuncStack,(int &)st1);//1出栈 move(s,st1->x,st1->n,st1->z,step);//生成字命令符串 MoveCMDTrans(s,a,b,c,step);//解释执行移动圆盘命令 free(st1); //相当于move(x,n,z) if(!StackEmpty(FuncStack)){ Pop(FuncStack,(int &)st1);//退栈 move(s,st1->x,st1->n,st1->z,step);//生成字命令符串 MoveCMDTrans(s,a,b,c,step);//解释执行移动圆盘命令 //相当于hanoi(n-1,y,x,z) makeStSpace(st2);//申请保存一个状态的空间 letSt(st2,st1->n-1,st1->y,st1->x,st1->z);//给此状态赋值 Push(FuncStack,(int)st2);//将状态压栈 free(st1); } } DestroyStack(FuncStack);//销毁保存函数状态的栈 }//SolveStep Status ShowSolve(int n,char d) {//计算机自动演示求解过程,演示完成后不影响用户解决问题进程 int step=1;//保存步数 SqStack a,b,c;//a,b,c分别为储存A座,B座,C座状态的栈 InitStack(a);InitStack(b);InitStack(c);//对a,b,c进行初始化 printf("\n\n已进入计算机自动演示程序:\n\n"); InitQuestion(n,a);//对问题进行初始设置,即将圆盘依次摆在A座上 ShowCurrent(a,b,c);//输出当前汉诺塔状态 if(d=='s')//如果d='s'则用非递归求解演示 { //非递归求解 printf("非递归求解\n"); SolveStep(a,b,c,step,n); } else{ //递归算法求解 printf("递归求解\n"); hanoi(n,'A','B','C',a,b,c,step); } step=0; printf("\n\n演示结束,请继续……\n\n"); DestroyStack(a);DestroyStack(b);DestroyStack(c);//销毁a,b,c三个栈 return OK; }//ShowSolve void Goodbye(SqStack &a,SqStack &b,SqStack &c) {//显示结束画面,并结束程序 DestroyStack(a);DestroyStack(b);DestroyStack(c);//销毁a,b,c三个栈 system("cls"); printf("\n\n\n\n\t\t\tGoodbye\n\n"); printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n"); Pause();//按任意键继续 exit(0); }//Goodbye void InputNO(int &n) {//用户输入汉诺塔高度 printf("请输入汉诺塔高度(请输入1~9之间的整数,输入0退出程序):"); for(n=getch(); n<'0' || n>'9';n=getch()) { putch('\n'); printf("您输入的数据有误,请重新输入(请输入1~9之间的整数,输入0退出程序):"); }//for putch(n); putch('\n'); n=n-'0'; }//InputNO void Help() { printf("命令帮助:\n \ h/H-----命令帮助\n\ t/T-----输出当前汉诺塔状态\n\ s/S-----由计算机演示非递归求解过程(不影响用户的问题解决进程)\n \ d/D-----由计算机演示递归求解过程(不影响用户的问题解决进程)\n \ r/R-----重新开始\n \ n/N-----重新设置问题(被设置后问题将重新开始)\n \ x/X-----退出此程序\n \ ?-?-----移动命令,将A座盘子移动B座则可输入“a-b”,以此类推 \n\n"); } void OpenScreen()//开始画面 { system("color f0"); system("title 汉诺塔演示程序 WrittenBy huaying1988.com"); printf("\n\n\n\t\t\t汉诺塔演示程序\n"); printf("\t\t\thuaying1988.com 学号:******\n"); printf("\t\t\t**学院 **07-*\n"); printf("\n\t说明:\n\ 汉诺塔状态表示方式是用A,B,C分别表示底座,数字\n\ 表示盘子,所以最多只可以有9个盘子,越小的数字\n\ 表示的盘子越小,在移动过程中,小盘子不能移动到\n\ 大盘子底下……开始时所有盘子依次排在A座,所要\n\ 解决的问题是要把所有的盘子都依次移动到C座……\n\ GOOD LUCK!!!\n\n"); printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n"); Pause(); system("cls"); Help(); }//OpenScreen void CMDTrans(int &step,int &n,char *s,SqStack &a,SqStack &b,SqStack &c) {//将字符串命令解释执行并输出执行后的汉诺塔状态 switch(s[0]) { case 'x'://Pass Through case 'X'://退出命令 Goodbye(a,b,c);//显示结束画面,并结束程序 break; case 'r'://Pass Through case 'R'://重新开始命令 system("cls"); step=0; ClearStack(a);ClearStack(b);ClearStack(c);//把a,b,c清空 InitQuestion(n,a); printf("已重新开始……\n\n"); ShowCurrent(a,b,c); break; case 'n'://Pass Through case 'N'://重新设置问题命令 system("cls"); printf("\n重新设置问题:\n"); step=0; InputNO(n);//用户输入汉诺塔高度 if(n==0)Goodbye(a,b,c);//输入0时退出程序 ClearStack(a);ClearStack(b);ClearStack(c);//把a,b,c清空 InitQuestion(n,a); printf("问题已被重新设置,请重新开始……\n\n"); ShowCurrent(a,b,c); break; case 's'://Pass Through case 'S'://自动演示命令 ShowSolve(n,'s');//计算机自动演示求解过程,演示完成后不影响用户解决问题进程 ShowCurrent(a,b,c);//输出当前汉诺塔状态 break; case 'd'://Pass Through case 'D'://自动演示命令 ShowSolve(n,'d');//计算机自动演示求解过程,演示完成后不影响用户解决问题进程 ShowCurrent(a,b,c);//输出当前汉诺塔状态 break; case 'h'://Pass Through case 'H'://命令帮助 Help(); break; case 't'://Pass Through case 'T'://输出当前汉诺塔状态 ShowCurrent(a,b,c);//输出当前汉诺塔状态 break; default: //step++; printf("\n第%d步:\n",step+1); MoveCMDTrans(s,a,b,c,step);//解释执行移动圆盘命令 break; }//switch(s[0]) }//CMDTrans char *c1="aAbBcC"; char *c2="HhTtSsDdRrNnXx"; int instr(char c,char *str) {//判断字符c是否在str中 int i; for(i=0;str[i]!=0;i++) if(str[i]==c)return 1; return 0; }//instr int isCmd(char *cmd) {//判断是否为命令 if((instr(cmd[0],c2)&&cmd[1]==0)||(instr(cmd[0],c1)&&instr(cmd[2],c1)&&cmd[3]==0)) return 1; printf("无法识别的命令\n"); return 0; }//isCmd void InputCMD(char * s) {//用户输入命令 do{//不是命令则重新输入 printf("h-help,x-exit|请输入命令:\n"); scanf("%s",s); }while(!isCmd(s)); }//InputCMD //--------------------------------关于汉诺塔的函数 结束------------------------------- //--------------------------------------------主函数 开始-------------------------------------------------- int main() {//主函数 OpenScreen();//开始画面 char again;//是否再来一次 SqStack a,b,c;//a,b,c分别为储存A座,B座,C座状态的栈 char s[100];//用于保存用户输入的命令字串 InitStack(a);InitStack(b);InitStack(c);//声明栈并进行初始化 int n;//用户定义汉诺塔高度 int step;//用户步数 do { step=0; InputNO(n);//用户输入汉诺塔高度 if(n==0)Goodbye(a,b,c);//输入0时退出程序 InitQuestion(n,a);//对问题进行初始设置,即将圆盘依次摆在A座上 ShowCurrent(a,b,c);//输出当前汉诺塔状态 while(!Success(n,c))//判断问题是否已被解决 { InputCMD(s);//输入命令 CMDTrans(step,n,s,a,b,c);//将字符串命令解释执行并输出执行后的汉诺塔状态 }//while printf("恭喜你,你已经成功解决此问题!(共用了%d步)\n\n",step); printf("再来一次?(y/n)"); do again=getch();//读取输入字符 while(again!='y' && again!='n');//判断输入的是否为为‘y’或‘n’不是则重新输入 if(again=='y')//如果输入‘y’则进行初始化 { ClearStack(a);ClearStack(b);ClearStack(c);//把a,b,c清空 system("cls");//清屏 }//if }while(again=='y');//如果输入‘y’则继续循环 Goodbye(a,b,c);//结束函数 }//main //--------------------------------------------主函数 结束-------------------------------------------------- ``` ## 四、测试数据及结果分析: ### 运行界面: ![运行界面](hanoi.png "运行界面") ### 测试数据1: 开始画面以后,显示“请输入汉诺塔高度(请输入1~9之间的整数,输入0退出程序):” 输入“3” ,将汉诺塔高度初始化为3,显示: ``` 当前汉诺塔状态: A:321 B: C: h-help,x-exit|请输入命令: ``` 输入“s”查看计算机求解演示程序得到结果如下: ``` h-help,x-exit|请输入命令: s 已进入计算机自动演示程序: 当前汉诺塔状态: A:321 B: C: 非递归求解 第1步:将第1个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A:32 B: C:1 第2步:将第2个盘子从a座移动到b座 执行命令:a-b 从a移动到b,移动成功! 当前汉诺塔状态: A:3 B:2 C:1 第3步:将第1个盘子从c座移动到b座 执行命令:c-b 从c移动到b,移动成功! 当前汉诺塔状态: A:3 B:21 C: 第4步:将第3个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A: B:21 C:3 第5步:将第1个盘子从b座移动到a座 执行命令:b-a 从b移动到a,移动成功! 当前汉诺塔状态: A:1 B:2 C:3 第6步:将第2个盘子从b座移动到c座 执行命令:b-c 从b移动到c,移动成功! 当前汉诺塔状态: A:1 B: C:32 第7步:将第1个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A: B: C:321 演示结束,请继续…… 当前汉诺塔状态: A:321 B: C: h-help,x-exit|请输入命令: ``` 输入d可以查看递归求解过程,结果完全相同,也可以手动输入命令来完成求解,依次输入: a-c、a-b、c-b、a-c、b-a、b-c、a-c,此时屏幕提示: ``` 恭喜你,你已经成功解决此问题!(共用了7步) 再来一次?(y/n) 输入“y”重新设置问题并开始,输入“n”退出程序。 ``` ### 测试数据2: 将汉诺塔高度初始化为4,输入s查看结果: ``` h-help,x-exit|请输入命令: s 已进入计算机自动演示程序: 当前汉诺塔状态: A:4321 B: C: 非递归求解 第1步:将第1个盘子从a座移动到b座 执行命令:a-b 从a移动到b,移动成功! 当前汉诺塔状态: A:432 B:1 C: 第2步:将第2个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A:43 B:1 C:2 第3步:将第1个盘子从b座移动到c座 执行命令:b-c 从b移动到c,移动成功! 当前汉诺塔状态: A:43 B: C:21 第4步:将第3个盘子从a座移动到b座 执行命令:a-b 从a移动到b,移动成功! 当前汉诺塔状态: A:4 B:3 C:21 第5步:将第1个盘子从c座移动到a座 执行命令:c-a 从c移动到a,移动成功! 当前汉诺塔状态: A:41 B:3 C:2 第6步:将第2个盘子从c座移动到b座 执行命令:c-b 从c移动到b,移动成功! 当前汉诺塔状态: A:41 B:32 C: 第7步:将第1个盘子从a座移动到b座 执行命令:a-b 从a移动到b,移动成功! 当前汉诺塔状态: A:4 B:321 C: 第8步:将第4个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A: B:321 C:4 第9步:将第1个盘子从b座移动到c座 执行命令:b-c 从b移动到c,移动成功! 当前汉诺塔状态: A: B:32 C:41 第10步:将第2个盘子从b座移动到a座 执行命令:b-a 从b移动到a,移动成功! 当前汉诺塔状态: A:2 B:3 C:41 第11步:将第1个盘子从c座移动到a座 执行命令:c-a 从c移动到a,移动成功! 当前汉诺塔状态: A:21 B:3 C:4 第12步:将第3个盘子从b座移动到c座 执行命令:b-c 从b移动到c,移动成功! 当前汉诺塔状态: A:21 B: C:43 第13步:将第1个盘子从a座移动到b座 执行命令:a-b 从a移动到b,移动成功! 当前汉诺塔状态: A:2 B:1 C:43 第14步:将第2个盘子从a座移动到c座 执行命令:a-c 从a移动到c,移动成功! 当前汉诺塔状态: A: B:1 C:432 第15步:将第1个盘子从b座移动到c座 执行命令:b-c 从b移动到c,移动成功! 当前汉诺塔状态: A: B: C:4321 演示结束,请继续…… 当前汉诺塔状态: A:4321 B: C: h-help,x-exit|请输入命令: ``` 结果正确。 手动求解:依次输入a-b、a-c、b-c、a-b、c-a、c-b、a-b、a-c、b-c、b-a、c-a、b-c、a-b、a-c、b-c,求解成功! **注:转发请注明出处,以免老师误以为本人抄袭……**


发表评论

必填,公开,这样称呼起来方便~

必填,不会被公开,不必担心~

http://

非必填,公开,目的是方便增进友好访问~

必填,请输入下方图片中的字母或数字,以证明你是人类

看不清楚
必填,最好不要超过500个字符
     ↑返回顶端↑