汉诺塔问题
汉诺塔是一个经典的算法题,以下是其递归算法:
#include<iostream.h>
void hanio(int n,char,char,char);
void main()
{
char A='A',B='B',C='C';
int n=3;
hanio(n,A,B,C);
}
void hanio(int n,char A,char B,char C)
{
if(n==1)
{
cout<<"将第"<<n<<"个盘面从"<<A<<"柱搬到"<<C<<"柱上"<<endl;
}
else
{
hanio(n-1,A,C,B);
cout<<"将第"<<n<<"个盘面从"<<A<<"柱搬到"<<C<<"柱上"<<endl;
hanio(n-1,B,A,C);
}
}
运行结果是:
将第1个盘面从A柱搬到C柱上
将第2个盘面从A柱搬到B柱上
将第1个盘面从C柱搬到B柱上
将第3个盘面从A柱搬到C柱上
将第1个盘面从B柱搬到A柱上
将第2个盘面从B柱搬到C柱上
将第1个盘面从A柱搬到C柱上
这个不是从递归算法出发用栈消解得出的算法,而是直接从当前情况来判断移动的步骤。非递归算法:
#include<iostream.h>
#include<vector>
using namespace std;
class Needle
{
public:
Needle() { a.push_back(100); }
void push(int n) { a.push_back(n); }
int top() { return a.back(); }
int pop() { int n = a.back(); a.pop_back(); return n; }
int movenum(int n)
{ int i = 1;while (a[i] > n) i++; return a.size() - i; }
int size() { return a.size(); }
int operator [] (int n) { return a[n]; }
private:
vector<int> a;
};
void Hanoi(int n)
{
Needle needle[3], ns;
int source = 0, target, target_m = 2, disk, m = n;
for (int i = n; i > 0; i--)
needle[0].push(i);
while(n)
{
if(!m)
{
source = ns.pop();
target_m = ns.pop();
m = needle[source].movenum(ns.pop());
}
if(m % 2)
target = target_m;
else
target = 3 - source - target_m;
if(needle[source].top() < needle[target].top())
{
disk = needle[source].top();m--;
cout<< disk << " move " << (char)(source + 0x41)
<< " to "<< (char)(target + 0x41) << endl;
needle[target].push(needle[source].pop());
if(disk == n)
{ source = 1 - source; target_m = 2; m = --n; }
}
else
{
ns.push(needle[source][needle[source].size() - m]);
ns.push(target_m); ns.push(source);
m = needle[target].movenum(needle[source].top());
target_m = 3 - source - target; source = target;
}
}
}
void main()
{
Hanoi(6);//6个盘子的搬运过程
}