汉诺塔问题是递归思想的经典应用之一,即有一摞金蝶在塔1上,需要借助塔3把塔1的碟子移动到塔2上,限制是小碟子始终在大碟子上面。
这个问题用递归方法解决最为方便,即移动第N个碟子之前需要把塔1上的N-1个碟子移动到塔3上,再把碟子N移动到2上,再把塔3的N-1个碟子移动到塔2上。这样不断地递归就可以了。需要注意的是在递归过程中三个塔的形参会不断的变化,所以输出状态的时候需要做一个排序,详细实现见代码如下。
// Hannuota.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <vector>
#include <iomanip>
#include <iostream>
using namespace std;
class Hannuotan
{
public:
Hannuotan (char* initial) {Hname=initial;};
char *Hname;
int Hid;
vector<int> Hdata;
virtual ~Hannuotan(){
if (this->Hdata.size()!=0)
{
this->Hdata.clear();
}
};
};
void showhannota(Hannuotan& source,Hannuotan& dst,Hannuotan& temp)
{
cout<<"---------------------------"<<endl;
vector<Hannuotan> pool;
pool.push_back(source);
pool.push_back(dst);
pool.push_back(temp);
for (int i=0;i<3;i++)
for (int j=i+1;j<3;j++)
{
if (pool[i].Hid>pool[j].Hid)
{
swap(pool[i],pool[j]);
}
}
for (int i=0;i<3;i++)
{
cout<<setw(12)<<pool[i].Hname<<":";
for (int j=0;j<pool[i].Hdata.size();j++)
cout<<pool[i].Hdata[j]<<" ";
cout<<endl;
}
cout<<"---------------------------"<<endl;
}
void hannota(int n,Hannuotan& source,Hannuotan& dst,Hannuotan& temp,int &count)
{
int d=n;
if (n>0)
{
hannota(n-1,source,temp,dst,count);
dst.Hdata.push_back(n);
source.Hdata.pop_back();
count++;
showhannota(source,dst,temp);
hannota(n-1,temp,dst,source,count);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char s1[]="source";
char s2[]="destination";
char s3[]="temp";
Hannuotan Source(s1),Dst(s2),Temp(s3);
Source.Hid=1,Dst.Hid=2;Temp.Hid=3;
int top=5;
for (int j=top;j>0;j--)
{
Source.Hdata.push_back(j);
}
int count=0;
hannota(top,Source,Dst,Temp,count);
cout<<count<<endl;
return 0;
}
运行结果如下。