用堆栈实现汉诺塔。
初版代码:只能移动,不判断盘片大小,字符控制盘片移动。
// hanno.c
#include <iostream>
class FDSTACK{
/*
stack栈 按照后进先出LIFO规则运行。
堆栈的基本操作:
初始化
测试是否已满
进栈
出栈
检查栈顶元素
*/
/*
1.构造顺序堆栈
*/
#define EMPTY 0
#define FULL 1
#define PASS 2
#define FAIL 3
private:
int *stack;
int topStack;
int maxBuffer;
public:
FDSTACK(int bufferLength){ // 栈初始化
stack = new int[bufferLength];
this->maxBuffer = bufferLength;
}
~FDSTACK(){
free(stack);
}
void traversal(){ // 遍历堆栈数据
for(int i = 0; i <= topStack; i++){
std::cout << stack[i] << " ";
}
std::cout << std::endl;
}
int getBufferLength(){ // 获取堆栈长度
return this->maxBuffer;
}
int getCount(){ // 读取栈中元素个数
return this->topStack + 1;
}
void initialStack(){ // 初始化堆栈
topStack = -1;
}
int isEmpty(){ // 测试堆栈是否为空,为空返回0
return topStack == -1;
}
int isFull(){ // 测试堆栈是否已满,为满返回1
return topStack == (getBufferLength() - 1);
}
int pushStack(int data){ // 入栈 成功返回PASS,失败返回FAIL
if(isFull()){
return FAIL;
}else{
stack[++topStack] = data;
}
return PASS;
}
int popStack(){ // 出栈 成功返回数据
if(isEmpty()){
return FAIL;
}else{
return stack[topStack--];
}
}
int getTop(){ // 读取栈顶元素
if(isEmpty()){
return FAIL;
}else{
return stack[topStack];
}
}
};
void disp(FDSTACK *st){
}
int main(){
FDSTACK s[3] = {3,3,3};
s[0].initialStack();
s[1].initialStack();
s[2].initialStack();
/*
l 光标左移
r 光标右移
s 选中
p 放置
*/
char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp";
int temp = 0;
int select = 0;
for(int i = 3; i > 0; --i){ // hanno initial, 3block
s[0].pushStack(i);
}
for(int i = 0;i < sizeof(ctrlCode); i++){
switch(ctrlCode[i]){
case 'l':
select -= 1;
if(select < 0){
select = 0;
}
break;
case 'r':
select += 1;
if(select > 3){
select = 3;
}
break;
case 's':
temp = s[select].popStack();
break;
case 'p':
s[select].pushStack(temp);
break;
}
}
s[0].traversal();
s[1].traversal();
s[2].traversal();
std::cout << "----------" << std::endl;
return 0;
}
修改后的代码,添加插入检测功能,
对于三级汉诺塔,参考下面的操作指令序列:
char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp"; // 移动所有盘子到右边。
char ctrlCode[] = " srrpllsrrp"; // 一个错误的操作错误操作的输出,遇到非法操作时出现“error”提示,不做任何移动操作:
3 2 1
play count: 0
select: 0
cur: 0
----------
3 2
play count: 1
select: 1
cur: 0
----------
3 2
play count: 2
select: 1
cur: 1
----------
3 2
play count: 3
select: 1
cur: 2
----------
3 2
1
play count: 4
select: 1
cur: 2
----------
3 2
1
play count: 5
select: 1
cur: 1
----------
3 2
1
play count: 6
select: 1
cur: 0
----------
3
1
play count: 7
select: 2
cur: 0
----------
3
1
play count: 8
select: 2
cur: 1
----------
3
1
play count: 9
select: 2
cur: 2
----------
error
3
1
play count: 10
select: 2
cur: 2
----------
移动所有盘子到右边的输出,步骤略长:
3 2
play count: 0
select: 1
cur: 0
----------
3 2
play count: 1
select: 1
cur: 1
----------
3 2
play count: 2
select: 1
cur: 2
----------
3 2
1
play count: 3
select: 1
cur: 2
----------
3 2
1
play count: 4
select: 1
cur: 1
----------
3 2
1
play count: 5
select: 1
cur: 0
----------
3
1
play count: 6
select: 2
cur: 0
----------
3
1
play count: 7
select: 2
cur: 1
----------
3
2
1
play count: 8
select: 2
cur: 1
----------
3
2
1
play count: 9
select: 2
cur: 2
----------
3
2
play count: 10
select: 1
cur: 2
----------
3
2
play count: 11
select: 1
cur: 1
----------
3
2 1
play count: 12
select: 1
cur: 1
----------
3
2 1
play count: 13
select: 1
cur: 0
----------
2 1
play count: 14
select: 3
cur: 0
----------
2 1
play count: 15
select: 3
cur: 1
----------
2 1
play count: 16
select: 3
cur: 2
----------
2 1
3
play count: 17
select: 3
cur: 2
----------
2 1
3
play count: 18
select: 3
cur: 1
----------
2
3
play count: 19
select: 1
cur: 1
----------
2
3
play count: 20
select: 1
cur: 0
----------
1
2
3
play count: 21
select: 1
cur: 0
----------
1
2
3
play count: 22
select: 1
cur: 1
----------
1
3
play count: 23
select: 2
cur: 1
----------
1
3
play count: 24
select: 2
cur: 2
----------
1
3 2
play count: 25
select: 2
cur: 2
----------
1
3 2
play count: 26
select: 2
cur: 1
----------
1
3 2
play count: 27
select: 2
cur: 0
----------
3 2
play count: 28
select: 1
cur: 0
----------
3 2
play count: 29
select: 1
cur: 1
----------
3 2
play count: 30
select: 1
cur: 2
----------
3 2 1
play count: 31
select: 1
cur: 2
----------
3 2 1
play count: 32
select: 1
cur: 2
----------
最后的代码:
// hanno.c
#include <iostream>
class FDSTACK{
/*
stack栈 按照后进先出LIFO规则运行。
堆栈的基本操作:
初始化
测试是否已满
进栈
出栈
检查栈顶元素
*/
/*
1.构造顺序堆栈
*/
#define EMPTY 0
#define FULL 1
#define PASS 2
#define FAIL 3
private:
int *stack;
int topStack;
int maxBuffer;
public:
FDSTACK(int bufferLength){ // 栈初始化
stack = new int[bufferLength];
this->maxBuffer = bufferLength;
}
~FDSTACK(){
free(stack);
}
void traversal(){ // 遍历堆栈数据
for(int i = 0; i <= topStack; i++){
std::cout << stack[i] << " ";
}
std::cout << std::endl;
}
int getBufferLength(){ // 获取堆栈长度
return this->maxBuffer;
}
int getCount(){ // 读取栈中元素个数
return this->topStack + 1;
}
void initialStack(){ // 初始化堆栈
topStack = -1;
}
int isEmpty(){ // 测试堆栈是否为空,为空返回0
return topStack == -1;
}
int isFull(){ // 测试堆栈是否已满,为满返回1
return topStack == (getBufferLength() - 1);
}
int pushStack(int data){ // 入栈 成功返回PASS,失败返回FAIL
if(isFull()){
return FAIL;
}else{
stack[++topStack] = data;
}
return PASS;
}
int popStack(){ // 出栈 成功返回数据
if(isEmpty()){
return FAIL;
}else{
return stack[topStack--];
}
}
int getTop(){ // 读取栈顶元素
if(isEmpty()){
return FAIL;
}else{
return stack[topStack];
}
}
};
void disp(FDSTACK *st){
}
int main(){
FDSTACK s[3] = {3,3,3};
s[0].initialStack();
s[1].initialStack();
s[2].initialStack();
/*
l 光标左移
r 光标右移
s 选中
p 放置
*/
// char ctrlCode[] = "srrpllsrprslplsrrplslprsrpllsrrp";
char ctrlCode[] = " srrpllsrrp";
int temp = 0;
int select = 0;
int playCount = 0;
for(int i = 3; i > 0; --i){ // hanno initial, 3block
s[0].pushStack(i);
}
for(int i = 0;i < sizeof(ctrlCode); i++){
switch(ctrlCode[i]){
case 'l':
select -= 1;
if(select < 0){
select = 0;
}
break;
case 'r':
select += 1;
if(select > 3){
select = 3;
}
break;
case 's':
temp = s[select].popStack();
break;
case 'p':
if(s[select].isEmpty()){
s[select].pushStack(temp);
}else{
if(temp > s[select].getTop()){
std::cout << "error" << std::endl;
continue;
}else{
s[select].pushStack(temp);
}
}
break;
}
s[0].traversal();
s[1].traversal();
s[2].traversal();
std::cout << "play count: " << playCount << std::endl;
std::cout << "select: " << temp << std::endl;
std::cout << "cur: " << select << std::endl;
std::cout << "----------" << std::endl;
playCount++;
}
return 0;
}
本文详细介绍了如何使用堆栈数据结构实现汉诺塔问题,并加入了一个错误检测机制,确保操作指令序列的有效性。通过示例演示了正确执行指令序列将所有盘片移动到目标柱子的过程,以及遇到非法操作时的响应。
645

被折叠的 条评论
为什么被折叠?



