简单来说就是三个步骤
- 将前n-1个移动到辅助杆B上 hanoi(n-1,a,c,b)
- 将最后一个移动到目标杆C上 hanoi(1,a,b,c)
- 将前n-1个辅助杆上面的移动到目标杆上边 hanoi(n-1,b,a,c)
递归程序
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
void move(int id, char x, char y)
{
printf("%d : %c -> %c\n", id, x, y);
}
void hanoi(int n, char A, char B, char C)
{
if (n == 1)
{
move(n, A, C);
}
else
{
hanoi(n - 1, A, C, B);
move(n, A, C);
hanoi(n - 1, B, A, C);
}
}
main()
{
hanoi(3, 'A', 'B', 'C');
}
或者可以这样写
#include<iostream>
using namespace std;
void hanoi(int n,char a,char b,char c){
if(n==1){
//cout<<a <<" -> "<< c<<endl;
printf("%c -> %c\n",a,c);
}
else{
hanoi(n-1,a,c,b);
//cout<<a <<" -> "<< c<<endl;
printf("%c -> %c\n",a,c);
hanoi(n-1,b,a,c);
}
}
int main(){
int n;
scanf("%d",&n);
hanoi(n,'a','b','c');
}
非递归程序
由数据结构的知识得到,递归的本质是使用堆栈,先进后出。
那么既然汉诺塔问题可以用递归解决,一定有另一种方法可以用堆栈来解决,只不过程序看起来更加复杂。(貌似在学数据结构的时候pta上有一道非递归求解汉诺塔的问题,似乎当时直接提交递归的代码也能满分通过)
有一种算法可以解决,链接如下(?)
汉诺塔的递归与非递归实现(C++实现)_锦恢的博客-CSDN博客_汉诺塔的非递归实现
较为简单的代码如下
需要注意的是:push的内容为node(n,‘a’,‘b’,‘c’),不能像递归一样直接输入n,‘a’,‘b’,‘c’
#include<stack>
#include<iostream>
using namespace std;
struct node{
int n,a,b,c;
node(int m,int x,int y,int z):n(m),a(x),b(y),c(z){}
};
int main()
{
int n;
cin>>n;
stack<node> s; //堆栈
s.push(node(n,'a','b','c')); //入栈
while(!s.empty())
{
node t=s.top();
s.pop();
if(t.n==1) printf("%c -> %c\n",t.a,t.c);
else
{
s.push(node(t.n-1,t.b,t.a,t.c));
s.push(node(1,t.a,t.b,t.c));
s.push(node(t.n-1,t.a,t.c,t.b));
}
}
}