操作汉诺塔的算法一枚

用堆栈实现汉诺塔。


初版代码:只能移动,不判断盘片大小,字符控制盘片移动。

// 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 


play count: 4

select: 1

cur: 2

----------

3 2 


play count: 5

select: 1

cur: 1

----------

3 2 


play count: 6

select: 1

cur: 0

----------


play count: 7

select: 2

cur: 0

----------


play count: 8

select: 2

cur: 1

----------


play count: 9

select: 2

cur: 2

----------

error


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 


play count: 3

select: 1

cur: 2

----------

3 2 


play count: 4

select: 1

cur: 1

----------

3 2 


play count: 5

select: 1

cur: 0

----------


play count: 6

select: 2

cur: 0

----------


play count: 7

select: 2

cur: 1

----------

play count: 8

select: 2

cur: 1

----------

play count: 9

select: 2

cur: 2

----------


play count: 10

select: 1

cur: 2

----------


play count: 11

select: 1

cur: 1

----------

2 1 


play count: 12

select: 1

cur: 1

----------

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 

play count: 17

select: 3

cur: 2

----------


2 1 

play count: 18

select: 3

cur: 1

----------


play count: 19

select: 1

cur: 1

----------


play count: 20

select: 1

cur: 0

----------

play count: 21

select: 1

cur: 0

----------

play count: 22

select: 1

cur: 1

----------


play count: 23

select: 2

cur: 1

----------


play count: 24

select: 2

cur: 2

----------


3 2 

play count: 25

select: 2

cur: 2

----------


3 2 

play count: 26

select: 2

cur: 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值