【算法描述】
汉诺塔(Tower of Hanoi)问题源于印度传说。话说大梵天创造世界时造了三根金钢石柱子(假设为A、B、C),其中一根柱子(假设为A)自底向上叠着64片大小不同的黄金圆盘。有一天,大梵天命令婆罗门把圆盘从A柱移动C柱上。并且规定,在柱子间移动圆盘时,每次只能移动一个圆盘,且任何时候大圆盘不能放在小圆盘上。请给出算法代码。
【算法分析】
运用递归思想,可以高效简洁地解决问题。其核心是递归函数的设计。而递归函数设计的关键是将“大问题拆分成小问题”形式化。比如,汉诺塔问题要求将A柱子上的n个圆盘移到C柱子上。显然,根据题意不可能将A柱子上的n个圆盘一下子移到C柱子上,其必然需要借助B柱子。经过分析,此过程可形式化为大问题move(int n,char A,char B,char C),表示将n个圆盘由A柱借助B柱移到C柱。由于汉诺塔问题的递归性,所以大问题move(int n,char A,char B,char C)将被设计成一个递归函数。依据递归设计思想,需要在函数move(int n,char A,char B,char C)中进行递归调用才能将其实现为递归函数。而递归调用的典型设计是在递归调用时缩小某些参数的调用规模。如汉诺塔问题move(int n,char A,char B,char C)的递归调用实现方法是“将n-1个圆盘由A柱借助C柱移到B柱move(n-1, A,C,B)、将A柱最下边的一个圆盘移到C柱cout<<A<<"-->"B<<endl;、将n-1个圆盘由B柱借助A柱移到C柱move(n-1,B,A,C)”。可以清楚地看到,其中的递归调用参数规模由n缩小为n-1了。
【C++语言代码】
#include <iostream>
using namespace std;
int step=0;
void move(int tot,char x,char y,char z) {
if(tot==0) return;
move(tot-1,x,z,y); //x use z to y
step++;
cout<<step<<":"<<x<<"-->"<<z<<endl;
move(tot-1,y,x,z); //y use x to z
}
int main() {
cout<<"n=";
int n;
cin>>n;
move(n,'a','b','c');
return 0;
}
【C语言代码】
#include <stdio.h>
int step=0;
void move(int tot,char x,char y,char z) {
if(tot==0) return;
else {
move(tot-1,x,z,y); //x use z to y
step++;
printf("%d:%c-->%c\n",step,x,z);
move(tot-1,y,x,z); //y use x to z
}
}
int main() {
printf("n=");
int n;
scanf("%d",&n);
move(n,'a','b','c');
return 0;
}
【运行截图】