# 数据结构课程设计大曝光(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,求解成功!
**注:转发请注明出处,以免老师误以为本人抄袭……**