汉诺塔算法 c语言实验报告,C语言汉诺塔算法原理分析与实践

汉诺塔游戏的规则:如下图所示,有三个柱子A,B,C,我们要做的是把A柱的所有圆盘,全部转移到C柱上,转移时遵循的规则如下:

1、每次只能移动一个圆盘

2、所有的大圆盘必须在小圆盘的下面

74be753b23204aed9c0d936924be6323.jpg

首先假设只有一个圆盘,我们将其编号为1,如下图所示,那么这时候只需要将A直接移到C即可:

a41b63b6806340e785b7dba93def66de.jpg

当存在多个圆盘时:我们以三个为例观察现象

首先三个圆盘放在A柱上,按从上到下的顺序依次编号为1,2,3(最小的为1,最大的为3),我们先不考虑3号盘,而只考虑上面两个小一点的圆盘(编号1,2),而此前我们已经分析了两个圆盘的移动过程,那么这两个圆盘该移动到哪根柱子呢?目前只有B柱,C柱可选,而C柱肯定不行,因为C柱是目标柱,那么我们只能把1,2号盘从A柱移动到B柱,借助C柱,则移动过程为:A->C, A->B,C->B。此时,1,2号盘已经到达B柱,再把最大的三号盘,直接移到C柱。此时工作快要完成了,目前的状态为:1,2号盘在B柱,3号盘已到达目的柱C柱,再接下来,把1,2号盘将B柱移动到C柱,转移工作就彻底结束,借助A柱,转移过程为:B->A,B->C,A->C。

函数定义

根据上面的分析,我们知道,函数的参数,有盘子,A,B,C三个柱子,所以,函数的签名为: func(n, a, b, c)。其中n表示圆盘的个数,a表示起始柱,b表示辅助柱,c表示目标柱。

def func(n,a,b,c):

if n == 1:

print(a,"-->",c)

else:

func(n-1,a,c,b)

print(a, '-->', c)

func(n-1,b,a,c)

if __name__ == '__main__':

func(4,'a','b','c')

68f1ee567f08436c807a944573312971.jpg

可以将代码理解为三个步骤:

func(n-1,a,c,b)

第一步:该递归是将A柱上n-1个圆盘借助c移动到b

4de5bdb72630491d9d49be910e1fae4a.jpg

2d450a9d67b24f6db967d9b52f9e0b80.png

print(a, '-->', c)

第二步:将第n个圆盘从a移动到c

b7d4ae03507147cdbf2c69700d8f27d9.jpg

func(n-1,b,a,c)

第三步:该递归将b柱上n-1个圆盘借助a移动到c

91a65b21dfbc4a8681318b843a490711.png

扩展:

C语言写汉诺塔递归算法

#include #include void Hanoi(int n, char a,char b,char c);

void Move(int n, char a, char b);

int count;

int main()

{

int n=8;

printf("汉诺塔的层数:\n");

scanf(" %d",&n);

Hanoi(n, 'A', 'B', 'C');

Sleep(20000);

return 0;

}

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);

}

}

void Move(int n, char a, char b)

{

count++;

printf("第%d次移动 Move %d: Move from %c to %c !\n",count,n,a,b);

}

### 汉诺塔算法递归实现 汉诺塔问题是典型的递归问题,其核心思想是将复杂的大规模问题逐步拆分为多个简单的子问题。以下是基于 Java 和 C 的两种实现方式。 #### Java 实现 在 Java 中,可以通过定义一个 `hanoi` 方法来完成递归逻辑。该方法接收四个参数:盘子的数量 (`n`)、起始柱子 (`fromRod`)、目标柱子 (`toRod`) 和辅助柱子 (`auxRod`)。当盘子数量为 1 时,直接执行基本操作;否则,继续调用自身处理剩余的盘子[^1]。 ```java public class HanoiTower { public static void hanoi(int n, String fromRod, String toRod, String auxRod) { if (n == 1) { System.out.println("将盘子 1 从 " + fromRod + " 移动到 " + toRod); return; } // 将前 n-1 个盘子从初始杆移动到辅助杆 hanoi(n - 1, fromRod, auxRod, toRod); // 将第 n 个盘子从初始杆移动到目标杆 System.out.println("将盘子 " + n + " 从 " + fromRod + " 移动到 " + toRod); // 将 n-1 个盘子从辅助杆移动到目标杆 hanoi(n - 1, auxRod, toRod, fromRod); } public static void main(String[] args) { int numberOfDisks = 3; // 可更改此值测试不同数量的盘子 hanoi(numberOfDisks, "A", "C", "B"); } } ``` #### C 实现 同样,在 C 编程语言中也可以采用类似的思路解决问题。下面展示的是标准 C 风格的递归实现方案[^2][^3]: ```c #include <stdio.h> void hanoi(int n, char A, char B, char C) { if (n == 1) { printf("将盘子 1 从 %c 移动到 %c\n", A, C); return; } // 将 n-1 个盘子从 A 移动到 B 使用 C 作为辅助 hanoi(n - 1, A, C, B); // 将第 n 个盘子从 A 移动到 C printf("将盘子 %d 从 %c 移动到 %c\n", n, A, C); // 将 n-1 个盘子从 B 移动到 C 使用 A 作为辅助 hanoi(n - 1, B, A, C); } int main() { int n; printf("请输入盘子个数:"); scanf("%d", &n); // 从 A 移动到 C,使用 B 作为辅助 hanoi(n, 'A', 'B', 'C'); return 0; } ``` 以上两段代码分别展示了如何用 Java 和 C 来解决汉诺塔问题,并且都遵循了相同的递归模式[^1]^。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值