```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 /* 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 /* 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; } ```