递归算法——入门汉诺塔

-----------------------------------------------------------------------瞎逼逼部分----------------------------------------------------------------------

递归算法是一个很让人头大的事情,现在我还是没理解汉诺塔是怎么实现的,看到大神们的代码就短短几行,但是我脑中的想法却有很多。

决定的实现方法是采用形象的桟,使用三个桟,分别表示三根柱子,利用循环结构给第一个柱子从大到小放入盘子。

利用全局指针指向三个桟,在每一次挪动过后,利用函数输出桟里面的元素。

好吧这些无关最重要部分

----------------------------------------------------------------------------------------------------------------------------------------------------------

下面是关键代码

void han(int n, mystack<int> &a, mystack<int> &b, mystack<int> &c) //这边形参使用了一个n,表示要转移数量,还有三个我自己定义的桟类指针,传递了三个塔的地址。
{
	int e;							  ///e用来辅助我的桟进出
	if (n == 1)						  *重点*:实际上所有的操作都在这边if条件成立的时候进行。
	{							所以要理解这一点很重要,因为你每次移动的都是一个盘子,相当于你的每一次操作都是n=1。
		a.pop(e);					///a栈顶元素出桟,并存储到e中。
		c.push(e);					将e进桟到c中。
		stout();					///这句不要纠结,只是我的输出函数,这样我就可以在每一次操作后看到三个桟的情况。
	}
	else							/else里面没有任何的直接移动,都是在调用自身这个函数。
	{							//先解释一下下面可能用到的词,要这样认为,广义上,a桟是起点桟,b桟是空闲桟,c桟是目标桟。这边的abc桟和我们定义的abc桟不一定是对应的。
		han(n - 1, a, c, b);				///将n-1个盘子移动到空闲桟上。
		han(1, a, b, c);				将起点桟上剩余的一个盘移动到目标桟。
		han(n - 1, b, a, c);				/再将空闲桟上的盘移动到目标桟上。
	}
}
所以就是这些了,以上就是实现汉诺塔的关键算法了。

---------------------------------------------------贴上完整代码,自己写的桟类。感兴趣的可以copy来调试一下,蹩脚注释请忽视---------------------------------------------

#include <iostream>
using namespace std;
//下面是我自己写的栈,还不会用标准库里面的,就自己写了一个
template <typename T>
class mystack
{
	T *data;
	int top;
public:
	mystack();
	~mystack();
	bool isempty();
	bool isfull();
	bool push(T e);
	bool getop(T &e);
	bool pop(T &e);
	void disp();
};
template <typename T>
mystack<T>::mystack()
{
	data = new T[100];
	top = -1;
}
template <typename T>
mystack<T>::~mystack()
{
	delete[] data;
}
template <typename T>
bool mystack<T>::isempty()
{
	return (top == -1);
}
template <typename T>
bool mystack<T>::isfull()
{
	return (top == 99);
}
template <typename T>
bool mystack<T>::push(T e)
{
	if (isfull())
		return false;
	else
	{
		top++;
		data[top] = e;
		return true;
	}
}
template <typename T>
bool mystack<T>::getop(T &e)
{
	if (isempty())
		return false;
	else
	{
		e = data[top];
		return true;
	}
}
template <typename T>
bool mystack<T>::pop(T &e)
{
	if (isempty())
		return false;
	else
	{
		e = data[top];
		top--;
		return true;
	}
}
template <typename T>
void mystack<T>::disp()
{
	int i = -1;
	while (i<top)
	{
		i++;
		cout << "|" << data[i];
	}
	cout << "|" << endl;
}
///这是我的输出函数,可以输出三个塔里面的元素
mystack<int> *pa, *pb, *pc;
int ct = 1;
void stout()
{
	cout << "Step " << ct << ":" << endl;
	pa->disp();
	pb->disp();
	pc->disp();
	ct++;
}
下面是关键函数
void han(int n, mystack<int> &a, mystack<int> &b, mystack<int> &c)
{
	int e;
	if (n == 1)
	{
		a.pop(e);
		c.push(e);
		stout();
	}
	else
	{
		han(n - 1, a, c, b);
		han(1, a, b, c);
		han(n - 1, b, a, c);
	}
}
/下面是main函数
int main()
{
again:
	ct = 1;
	system("cls");
	int n;
	cout << "Please enter the number of the plate." << endl;
	cin >> n;
	system("cls");
	mystack<int> a;
	mystack<int> b;
	mystack<int> c;
	pa = &a;
	pb = &b;
	pc = &c;
	for (int i = n; i>0; i--)
		a.push(i);
	a.disp();
	han(n, a, b, c);
	system("pause");
	goto again;
	return 0;
}

————————————————分割线————————————————————

有几个月了,现在暑假集训发现不止有经典汉诺塔,还有汉诺塔1到10;

感兴趣的小伙伴可以到杭电里面找一下,做了感觉有加深理解。



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值