汉诺塔问题:
给定三根柱子,记为 x、y和 z。起始状态下,柱子 x上套着 n 个圆盘,它们从上到下按照从小到大的顺序排列。我们的任务是要把这n个圆盘移到柱子 z上,并保持它们的原有顺序不变。在移动圆盘的过程中,需要遵守以下规则:
- 圆盘只能从一根柱子顶部拿出,从另一根柱子顶部放入。
- 每次只能移动一个圆盘。
- 小圆盘必须时刻位于大圆盘之上。
汉诺塔问题的递归/非递归解决方案
总思路:hanoi(n,x,y,z)将x杆的n个盘子经y杆,放到z杆
- 把 n-1 只碟子从x杆经z杆移动到y杆
- 将X杆上第n只碟子移到Z杆
- 将n-1只碟子从Y杆经X杆移动到Z杆
移动
void move(char a,char b){
printf("%c---->%c\n",a,b);//将a杆顶上的碟子移动到b杆顶上
}
递归解决
void hanoi(int n,char x,char y,char z){
if(n==1){
move(x,z);
}else{
hanoi(n-1,x,z,y);
move(a,c);
hanoi(n-1,y,x,z);
}
}
非递归解决
结构体定义
typedef struct{
int n;
char x,y,z;
}Hanoi;
Hanoi s[100];
int hanoi_top = -1;
入栈函数
void Push(int n,char x,char y,char z){
++hanoi_top;
s[hanoi_top].n = n;
s[hanoi_top].x = x;
s[hanoi_top].y = y;
s[hanoi_top].z = z;
}
实现:注意栈后入先出LIFO的特性
void solveHanoi(int n){
Push(n,'x','y','z');
while(hanoi_top>=0){
Hanoi top = s[hanoi_top];
--hanoi_top;
if(1 == top.n){
move(top.x,top.z);
}else{
/**
由于栈先入后出的特性,入栈操作顺序应当与实际操作顺序相反
*/
Push(top.n-1,top.y,top.x,top.z);
Push(1,top.x,top.y,top.z);
Push(top.n-1,top.x,top.z,top.y);
}
}
}