数据结构实验报告移动盘片问题.docx
《数据结构实验报告移动盘片问题.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告移动盘片问题.docx(9页珍藏版)》请在冰豆网上搜索。
数据结构实验报告移动盘片问题
实验题目
移动盘片问题
小组合作
无
姓名
班级
学号
一、实验目的
递归到非递归的转换
二.实验环境
VC++6.0
三、实验内容与步骤
1.使用递归算法解Hanoi问题
//----递归算法------------------------------------------
voidHanoi1(intn,chara,charb,charc)
{
if(n==1)
printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
else
{
Hanoi1(n-1,a,c,b);
printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
Hanoi1(n-1,b,a,c);
}
}
2.转换为等价的非递归算法
//----非递归算法------------------------------------------
typedefstruct
{intn;//盘片个数
charx,y,z;//3个塔座
boolflag;//可直接移动盘片时为true,否则为false
}ElemType;//顺序栈中元素类型
typedefstruct
{ElemTypedata[MaxSize];//存放元素
inttop;//栈顶指针
}StackType;//声明顺序栈类型
3.编写求解Hanoi问题对应顺序栈的基本运算算法
voidInitStack(StackType*&s)//初始化栈
{s=(StackType*)malloc(sizeof(StackType));
s->top=-1;
}
voidDestroyStack(StackType*&s)//销毁栈
{
free(s);
}
boolStackEmpty(StackType*s)//判断栈是否为空
{
return(s->top==-1);
}
boolPush(StackType*&s,ElemTypee)//进栈
{if(s->top==MaxSize-1)
returnfalse;
s->top++;
s->data[s->top]=e;
returntrue;
}
boolPop(StackType*&s,ElemType&e)//出栈
{if(s->top==-1)
returnfalse;
e=s->data[s->top];
s->top--;
returntrue;
}
voidHanoi2(intn,charx,chary,charz)
{StackType*st;//定义顺序栈指针
ElemTypee,e1,e2,e3;
if(n<=0)return;//参数错误时直接返回
InitStack(st);//初始化栈
e.n=n;e.x=x;e.y=y;e.z=z;e.flag=false;
Push(st,e);//元素e进栈
while(!
StackEmpty(st))//栈不空循环
{Pop(st,e);//出栈元素e
if(e.flag==false)//当不能直接移动盘片时
{
e1.n=e.n-1;e1.x=e.y;e1.y=e.x;e1.z=e.z;
if(e1.n==1)//只有一个盘片时可直接移动
e1.flag=true;
else//有一个以上盘片时不能直接移动
e1.flag=false;
Push(st,e1);//处理Hanoi(n-1,y,x,z)步骤
e2.n=e.n;e2.x=e.x;e2.y=e.y;e2.z=e.z;e2.flag=true;
Push(st,e2);//处理move(n,x,z)步骤
e3.n=e.n-1;e3.x=e.x;e3.y=e.z;e3.z=e.y;
if(e3.n==1)//只有一个盘片时可直接移动
e3.flag=true;
else
e3.flag=false;//有一个以上盘片时不能直接移动
Push(st,e3);//处理Hanoi(n-1,x,z,y)步骤
}
else//当可以直接移动时
printf("\t将第%d个盘片从%c移动到%c\n",e.n,e.x,e.z);
}
DestroyStack(st);//销毁栈
}
四、实验过程与分析
实验程序
#include
#include
#defineMaxSize100
voidHanoi1(intn,chara,charb,charc)
{
if(n==1)
printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
else
{
Hanoi1(n-1,a,c,b);
printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
Hanoi1(n-1,b,a,c);
}
}
typedefstruct
{intn;//盘片个数
charx,y,z;//3个塔座
boolflag;//可直接移动盘片时为true,否则为false
}ElemType;//顺序栈中元素类型
typedefstruct
{ElemTypedata[MaxSize];//存放元素
inttop;//栈顶指针
}StackType;//声明顺序栈类型
voidInitStack(StackType*&s)//初始化栈
{s=(StackType*)malloc(sizeof(StackType));
s->top=-1;
}
voidDestroyStack(StackType*&s)//销毁栈
{
free(s);
}
boolStackEmpty(StackType*s)//判断栈是否为空
{
return(s->top==-1);
}
boolPush(StackType*&s,ElemTypee)//进栈
{if(s->top==MaxSize-1)
returnfalse;
s->top++;
s->data[s->top]=e;
returntrue;
}
boolPop(StackType*&s,ElemType&e)//出栈
{if(s->top==-1)
returnfalse;
e=s->data[s->top];
s->top--;
returntrue;
}
voidHanoi2(intn,charx,chary,charz)
{StackType*st;//定义顺序栈指针
ElemTypee,e1,e2,e3;
if(n<=0)return;//参数错误时直接返回
InitStack(st);//初始化栈
e.n=n;e.x=x;e.y=y;e.z=z;e.flag=false;
Push(st,e);//元素e进栈
while(!
StackEmpty(st))//栈不空循环
{Pop(st,e);//出栈元素e
if(e.flag==false)//当不能直接移动盘片时
{
e1.n=e.n-1;e1.x=e.y;e1.y=e.x;e1.z=e.z;
if(e1.n==1)//只有一个盘片时可直接移动
e1.flag=true;
else//有一个以上盘片时不能直接移动
e1.flag=false;
Push(st,e1);//处理Hanoi(n-1,y,x,z)步骤
e2.n=e.n;e2.x=e.x;e2.y=e.y;e2.z=e.z;e2.flag=true;
Push(st,e2);//处理move(n,x,z)步骤
e3.n=e.n-1;e3.x=e.x;e3.y=e.z;e3.z=e.y;
if(e3.n==1)//只有一个盘片时可直接移动
e3.flag=true;
else
e3.flag=false;//有一个以上盘片时不能直接移动
Push(st,e3);//处理Hanoi(n-1,x,z,y)步骤
}
else//当可以直接移动时
printf("\t将第%d个盘片从%c移动到%c\n",e.n,e.x,e.z);
}
DestroyStack(st);//销毁栈
}
intmain()
{
intn=3;
printf("递归算法:
%d个盘片移动过程:
\n",n);
Hanoi1(n,'X','Y','Z');
printf("非递归算法:
%d个盘片移动过程:
\n",n);
Hanoi2(n,'X','Y','Z');
return1;
}
实验截图
五、实验总结
对于不是尾递归的复杂递归算法,在理解递归调用实现过程的基础上可以用栈来模拟递归执行过程,从而将其转换为等价的非递归算法。
可以让栈中的每一个元素对应一个求解任务,可用flag来标识该任务是否可以直接移动盘片。