汉诺塔问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
XXXX大学信息学院
课程设计报告
教师签名:xxxxx
题目1实验报告
1.数据结构定义
因为该算法需要用到循环队列、堆和线性表,因此采用以下数据类型:
typedef struct
{
QElemType *base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;//循环队列
typedef struct
{
int *elem;
int length;
int listsize;
}SqList;//堆排序
2.算法说明
void HeapAdjust(int flag,SqList &H,int s,int m)
void HeapSort(int flag,SqList &H)//对H进行堆排序;
Status InitQueue(SqQueue &Q)//构造一个空队列Q,该队列预定义大小为MAXQSIZE;
Status EnQueue(SqQueue &Q,QElemType e) //插入元素e为Q的新的队尾元素;
Status DeQueue(SqQueue &Q, QElemType &e) // 若队列不空, 则删除Q的队头元素, 用e 返回其值, 并返回OK; 否则返回ERROR;
Status GetHead(SqQueue Q, QElemType &e)// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR;
Status QueueLength(SqQueue Q) // 返回Q的元素个数;
Status QueueTraverse(SqQueue Q)// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
3.用户使用说明
运行程序,根据屏幕上的文字提示一步步操作。
4.个人测试结果(截图)
部分测试结果截图
题目2实验报告
用堆栈实现汉诺塔问题的非递归求解抽象数据类型栈(stack)的定义:栈是限定仅在表尾进行插入或删除操作的线性表。栈又称为后进先出的线性表(简称LIFO结构),对栈来说,表尾端称为栈顶(top),相应的,表头端称为栈底(bottom),不含元素的空表称为空栈。
栈有两种存储表示方法:顺序栈和链栈,本次实验采用栈的顺序存储结构。
n阶汉诺塔问题的描述:假设有3个分别命名为X,Y和Z的塔座,在塔座X上插有n 个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将X塔座上的n个圆盘移至Z塔座上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:
(1)每次只能移动一个圆盘;
(2)圆盘可以插在X、Y和Z中的任一塔座上;
(3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
该道题可以用递归的的方法解决,算法思想如下:
假如只有一个圆盘,即n=1,只需将编号为1的圆盘从X移到Z;
假如n>1,移动的过程可分解为三个步骤:第一步把X上的n-1个圆盘移到Y上,Z 作辅助塔;第二步把X上的一个圆盘移到Z上;第三步把Y上的n-1个圆盘移到Z上,X作辅助塔;其中第一步和第三步是类同的。
C代码的实现如下:
if(n==1)
move(x,z);
else
{
hanoi(n-1,x,z,y);
move(first,third);
hanoi(n-1,y,x,z);
}
下面给出用堆栈实现汉诺塔的非递归解法:
void hanoi(st ta[], long max)//移动汉诺塔的主要函数
{
int k = 0;
int i = 0;
int ch;
while (k < max)
{//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子
ch = ta[i%3].Pop();
ta[(i+1)%3].Push(ch);
cout << ++k << ": " << ta[i%3].name <<
"--->" << ta[(i+1)%3].name << endl;
i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上
if (k < max)
{//把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小圆盘if (ta[(i+1)%3].Top() == 0 ||
ta[(i-1)%3].Top() > 0 &&
ta[(i+1)%3].Top() > ta[(i-1)%3].Top())
{
ch = ta[(i-1)%3].Pop();
ta[(i+1)%3].Push(ch);
cout << ++k << ": " << ta[(i-1)%3].name
<< "--->" << ta[(i+1)%3].name << endl;
}
else
{
ch = ta[(i+1)%3].Pop();
ta[(i-1)%3].Push(ch);
cout << ++k << ": " << ta[(i+1)%3].name
<< "--->" << ta[(i-1)%3].name << endl;
}
}