112 lines
3.0 KiB
Markdown
112 lines
3.0 KiB
Markdown
```c
|
||
/*
|
||
这段代码实现的是经典的 汉诺塔问题 的递归解法。
|
||
汉诺塔问题 是一个数学问题,具体描述如下:
|
||
给定三个柱子:A、B、C;
|
||
有若干个大小不等的圆盘(通常为n个),初始时所有圆盘都堆叠在A柱子上,从小到大按顺序叠放;
|
||
目标是将这些圆盘从A柱子移动到C柱子上,并且每次只能移动一个圆盘,且大的圆盘不能放在小的圆盘上面。
|
||
在这段代码中,hanoi 函数递归地解决了这个问题,参数 n 表示要移动的圆盘数,x、y、z 分别表示源柱子、辅助柱子和目标柱子。
|
||
代码详解:
|
||
基本思路:
|
||
如果只有一个盘子(n == 1),直接从 x 移动到 z。
|
||
如果有多个盘子(n > 1),可以通过以下步骤完成: 先将前 n-1 个盘子从 x 移到 y,这时 z 作为辅助柱子。
|
||
将第 n 个盘子从 x 移动到 z。
|
||
最后将 n-1 个盘子从 y 移到 z,这时 x 作为辅助柱子。
|
||
函数 hanoi 的参数:
|
||
n:表示要移动的圆盘的数量。
|
||
x:源柱子。
|
||
y:辅助柱子。
|
||
z:目标柱子。
|
||
递归过程:
|
||
对于每个递归调用,问题规模逐渐减小,最终会到达只有一个盘子的情况(基准条件)。
|
||
程序输出:
|
||
A -> C
|
||
A -> B
|
||
C -> B
|
||
这个输出表示了将两个圆盘从A柱子移动到C柱子所需的步骤。输出结果每一行表示一个移动的操作。
|
||
总结:
|
||
这段代码是解决汉诺塔问题的经典递归解法。通过分而治之的策略,把问题分解为更小的子问题来求解。
|
||
*/
|
||
```
|
||
|
||
### 函数递归打印汉诺塔移动步骤
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
|
||
/*
|
||
n:盘片数
|
||
x:源柱子
|
||
y:中间柱子
|
||
z:目标柱子
|
||
|
||
判断盘子个数:
|
||
如果只有一个盘子,那么直接搬到目标柱子
|
||
否则先将上面的n-1的盘子通过目标柱子移
|
||
动到非目标柱子上后再将剩下的最大的盘子移动到目标柱子
|
||
|
||
*/
|
||
//n的盘子从x通过y移动到z
|
||
void hanoi(int n, char x, char y, char z){
|
||
if(n == 1){
|
||
printf("%c -> %c\n", x, z);
|
||
}else{
|
||
hanoi(n-1, x, z, y);
|
||
printf("%c -> %c\n", x, z);
|
||
hanoi(n-1, y, x, z);
|
||
}
|
||
}
|
||
|
||
int main(void){
|
||
|
||
hanoi(3, 'A', 'B', 'C');
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
|
||
|
||
### 函数递归求汉诺塔移动的次数
|
||
|
||
```c
|
||
#include <stdio.h>
|
||
|
||
/*
|
||
n:盘片数
|
||
x:源柱子
|
||
y:中间柱子
|
||
z:目标柱子
|
||
|
||
判断盘子个数:
|
||
如果只有一个盘子,那么直接搬到目标柱子
|
||
否则先将上面的n-1的盘子通过目标柱子移
|
||
动到非目标柱子上后再将剩下的最大的盘子移动到目标柱子
|
||
|
||
*/
|
||
//n的盘子从x通过y移动到z
|
||
//int count = 0;//移动盘片的次数
|
||
//而不是只经过B柱子的次数
|
||
int hanoi(int n, char x, char y, char z){
|
||
int count = 0;//局部变量 用来存储当前这次函数调用中的移动盘子的次数
|
||
if(n == 1){
|
||
//printf("%c -> %c\n", x, z);
|
||
count++;
|
||
}else{
|
||
count += hanoi(n-1, x, z, y);
|
||
//printf("%c -> %c\n", x, z);
|
||
count++;
|
||
count += hanoi(n-1, y, x, z);
|
||
}
|
||
return count;
|
||
}
|
||
|
||
int main(void){
|
||
|
||
printf("%d\n", hanoi(3, 'A', 'B', 'C'));
|
||
|
||
return 0;
|
||
}
|
||
```
|
||
|